1  /-
  2  Copyright (c) 2016 Microsoft Corporation. All rights reserved.
  3  Released under Apache 2.0 license as described in the file LICENSE.
  4  Authors: Leonardo de Moura, Jeremy Avigad
  5  -/
  6  prelude
  7  import init.data.nat.basic init.data.nat.div init.meta init.algebra.functions
src         └─────────────────┘ └───────────────┘ └───────┘ └────────────────────┘
  8  universes u
  9  
 10  namespace nat
 11  attribute [pre_smt] nat_zero_eq_zero
id                       └──────────────┘
src                      └──────────────┘
typ                      └──────────────┘
doc             └─────┘
 12  
 13  protected lemma add_comm : ∀ n m : ℕ, n + m = m + n
id                                             
src                                              
typ                                            
 14  | n 0     := eq.symm (nat.zero_add n)
id               └─────┘  └──────────┘
src               └─────┘  └──────────┘
typ              └─────┘  └──────────┘
 15  | n (m+1) :=
id       
src        
typ      
 16    suffices succ (n + m) = succ (m + n), from
id              └──┘         └──┘    
src             └──┘         └──┘    
typ             └──┘         └──┘    
 17      eq.symm (succ_add m n) ▸ this,
id       └─────┘  └──────┘       └──┘
src      └─────┘  └──────┘      
typ      └─────┘  └──────┘       └──┘
 18    congr_arg succ (add_comm n m)
id     └───────┘ └──┘  └──────┘
src    └───────┘ └──┘  └──────┘
typ    └───────┘ └──┘  └──────┘
 19  
 20  protected lemma add_assoc : ∀ n m k : ℕ, (n + m) + k = n + (m + k)
id                                                       
src                                                          
typ                                                      
 21  | n m 0        := rfl
id                     └─┘
src                    └─┘
typ                    └─┘
 22  | n m (succ k) := by rw [add_succ, add_succ, add_assoc]
id          └──┘              └──────┘  └──────┘  └───────┘
src         └──┘          └──┘└──────┘└┘└──────┘└┘└───────┘└─
typ         └──┘          └──┘└──────┘└┘└──────┘└┘└───────┘└─
doc                       └──┘        └┘        └┘         └─
txt                       └──┘        └┘        └┘         └─
par                       └──┘        └┘        └┘         └─
pid                         └┘        └┘        └┘         
st                       └───────────┘└────────┘└─────────┘
 23  
src  
typ  
doc  
txt  
par  
pid  
st   
 24  protected lemma add_left_comm : ∀ (n m k : ℕ), n + (m + k) = m + (n + k) :=
id                                                              
src                                                                 
typ                                                             
 25  left_comm nat.add nat.add_comm nat.add_assoc
id   └───────┘ └─────┘ └──────────┘ └───────────┘
src  └───────┘ └─────┘ └──────────┘ └───────────┘
typ  └───────┘ └─────┘ └──────────┘ └───────────┘
 26  
 27  protected lemma add_left_cancel : ∀ {n m k : ℕ}, n + m = n + k → m = k
id                                                             
src                                                                
typ                                                            
 28  | 0        m k := by simp [nat.zero_add] {contextual := tt}
id                              └──────────┘                 └┘
src                       └────┘└──────────┘└┘ └────────────┘└┘└┘
typ                       └────┘└──────────┘└┘ └────────────┘└┘└┘
doc                       └────┘            └┘ └────────────┘  └┘
txt                       └────┘            └┘ └────────────┘  └┘
par                       └────┘            └┘ └────────────┘  └┘
pid                                        └────────────┘  
st                       └──────────────────────────────────────┘
 29  | (succ n) m k := λ h,
id      └──┘          
src     └──┘
typ     └──┘          
 30    have n+m = n+k, by { simp [succ_add] at h, assumption },
id                             └──────┘
src                      └────┘└──────┘└────┘  └─────────┘
typ                      └────┘└──────┘└────┘  └─────────┘
doc                         └────┘        └────┘  └─────────┘
txt                         └────┘        └────┘  └─────────┘
par                         └────┘        └────┘  └─────────┘
pid                                     └──┘            
st                       └─────────────────────┘└───────────┘└┘
 31    add_left_cancel this
id     └─────────────┘ └──┘
src    └─────────────┘
typ    └─────────────┘ └──┘
 32  
 33  protected lemma add_right_cancel {n m k : ℕ} (h : n + m = k + m) : n = k :=
id                                                                
src                                                                   
typ                                                               
 34  have m + n = m + k, by rwa [nat.add_comm n m, nat.add_comm k m] at h,
id                        └──────────┘    └──────────┘  
src                      └───┘└──────────┘  └┘└──────────┘  └────┘
typ                  └───┘└──────────┘└┘└──────────┘└────┘
doc                         └───┘              └┘              └────┘
txt                         └───┘              └┘              └────┘
par                         └───┘              └┘              └────┘
pid                            └┘              └┘              └───┘
st                         └────────────────────┘└────────────────┘└───┘
 35  nat.add_left_cancel this
id   └─────────────────┘ └──┘
src  └─────────────────┘
typ  └─────────────────┘ └──┘
 36  
 37  lemma succ_ne_zero (n : ℕ) : succ n ≠ 0 :=
id                               └──┘  
src                              └──┘   
typ                              └──┘  
 38  assume h, nat.no_confusion h
id            └──────────────┘ 
src            └──────────────┘
typ           └──────────────┘ 
 39  
 40  lemma succ_ne_self : ∀ n : ℕ, succ n ≠ n
id                               └──┘   
src                               └──┘   
typ                              └──┘   
 41  | 0     h := absurd h (nat.succ_ne_zero 0)
id               └────┘    └──────────────┘
src               └────┘    └──────────────┘
typ              └────┘    └──────────────┘
 42  | (n+1) h := succ_ne_self n (nat.no_confusion h (λ h, h))
id             └──────────┘    └──────────────┘        
src                              └──────────────┘
typ            └──────────┘    └──────────────┘        
 43  
 44  protected lemma one_ne_zero : 1 ≠ (0 : ℕ) :=
id                                         
src                                        
typ                                        
 45  assume h, nat.no_confusion h
id            └──────────────┘ 
src            └──────────────┘
typ           └──────────────┘ 
 46  
 47  protected lemma zero_ne_one : 0 ≠ (1 : ℕ) :=
id                                         
src                                        
typ                                        
 48  assume h, nat.no_confusion h
id            └──────────────┘ 
src            └──────────────┘
typ           └──────────────┘ 
 49  
 50  instance : zero_ne_one_class ℕ :=
id              └───────────────┘ 
src             └───────────────┘ 
typ             └───────────────┘ 
 51  { zero := 0, one := 1, zero_ne_one := nat.zero_ne_one }
id                                         └─────────────┘
src                                        └─────────────┘
typ                                        └─────────────┘
 52  
 53  lemma eq_zero_of_add_eq_zero_right : ∀ {n m : ℕ}, n + m = 0 → n = 0
id                                                            
src                                                               
typ                                                           
 54  | 0     m := by simp [nat.zero_add]
id                         └──────────┘
src                  └────┘└──────────┘└┘
typ                  └────┘└──────────┘└┘
doc                  └────┘            └┘
txt                  └────┘            └┘
par                  └────┘            └┘
pid                                  
st                  └───────────────────┘
 55  | (n+1) m := λ h,
id                 
src      
typ                
 56    begin
st     └─────
 57      exfalso,
src      └─────┘
typ      └─────┘
doc      └─────┘
txt      └─────┘
par      └─────┘
st   ──────────┘└─
 58      rw [add_one, succ_add] at h,
id           └─────┘  └──────┘
src      └──┘└─────┘└┘└──────┘└────┘
typ      └──┘└─────┘└┘└──────┘└────┘
doc      └──┘       └┘        └────┘
txt      └──┘       └┘        └────┘
par      └──┘       └┘        └────┘
pid        └┘       └┘        └───┘
st   ──────────────┘└────────┘└───┘└─
 59      apply succ_ne_zero _ h
id             └──────────┘   
src      └────┘└──────────┘└─┘ 
typ      └────┘└──────────┘└─┘
doc      └────┘            └─┘ 
txt      └────┘            └─┘ 
par      └────┘            └─┘ 
pid                       └─┘ 
st   ───────────────────────────
 60    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
 61  
 62  lemma eq_zero_of_add_eq_zero_left {n m : ℕ} (h : n + m = 0) : m = 0 :=
id                                                             
src                                                               
typ                                                            
 63  @eq_zero_of_add_eq_zero_right m n (nat.add_comm n m ▸ h)
id    └──────────────────────────┘    └──────────┘    
src   └──────────────────────────┘      └──────────┘     
typ   └──────────────────────────┘    └──────────┘    
 64  
 65  @[simp]
doc    └──┘
 66  lemma pred_zero : pred 0 = 0 :=
id                     └──┘   
src                    └──┘   
typ                    └──┘   
 67  rfl
id   └─┘
src  └─┘
typ  └─┘
 68  
 69  @[simp]
doc    └──┘
 70  lemma pred_succ (n : ℕ) : pred (succ n) = n :=
id                            └──┘  └──┘    
src                           └──┘  └──┘    
typ                           └──┘  └──┘    
 71  rfl
id   └─┘
src  └─┘
typ  └─┘
 72  
 73  protected lemma mul_zero (n : ℕ) : n * 0 = 0 :=
id                                         
src                                         
typ                                        
 74  rfl
id   └─┘
src  └─┘
typ  └─┘
 75  
 76  lemma mul_succ (n m : ℕ) : n * succ m = n * m + n :=
id                               └──┘       
src                               └──┘         
typ                              └──┘       
 77  rfl
id   └─┘
src  └─┘
typ  └─┘
 78  
 79  protected theorem zero_mul : ∀ (n : ℕ), 0 * n = 0
id                                             
src                                             
typ                                            
 80  | 0        := rfl
id                 └─┘
src                └─┘
typ                └─┘
 81  | (succ n) := by rw [mul_succ, zero_mul]
id      └──┘              └──────┘  └──────┘
src     └──┘          └──┘└──────┘└┘└──────┘└─
typ     └──┘          └──┘└──────┘└┘└──────┘└─
doc                   └──┘        └┘        └─
txt                   └──┘        └┘        └─
par                   └──┘        └┘        └─
pid                     └┘        └┘        
st                   └───────────┘└────────┘
 82  
src  
typ  
doc  
txt  
par  
pid  
st   
 83  private meta def sort_add :=
id                    └──────┘
typ                   └──────┘
 84  `[simp [nat.add_assoc, nat.add_comm, nat.add_left_comm]]
src    └────┘             └┘            └┘                 
typ    └────┘             └┘            └┘                 
doc    └────┘             └┘            └┘                 
txt    └────┘             └┘            └┘                 
par    └────┘             └┘            └┘                 
pid                     └┘            └┘                 
 85  
 86  lemma succ_mul : ∀ (n m : ℕ), (succ n) * m = (n * m) + m
id                                └──┘            
src                                └──┘               
typ                               └──┘            
 87  | n 0        := rfl
id                   └─┘
src                  └─┘
typ                  └─┘
 88  | n (succ m) :=
id        └──┘
src       └──┘
typ       └──┘
 89    begin
st     └─────
 90      simp [mul_succ, add_succ, succ_mul n m],
id             └──────┘  └──────┘  └──────┘  
src      └────┘└──────┘└┘└──────┘└┘          
typ      └────┘└──────┘└┘└──────┘└┘└──────┘
doc      └────┘        └┘        └┘          
txt      └────┘        └┘        └┘          
par      └────┘        └┘        └┘          
pid                  └┘        └┘          
st   ──────────────────────────────────────────┘└─
 91      sort_add
id       └──────┘
src      └──────┘
typ      └──────┘
par      └──────┘
st   ───────────┘
 92    end
st   ────┘
 93  
 94  protected lemma right_distrib : ∀ (n m k : ℕ), (n + m) * k = n * k + m * k
id                                                              
src                                                                  
typ                                                             
 95  | n m 0        := rfl
id                     └─┘
src                    └─┘
typ                    └─┘
 96  | n m (succ k) :=
id          └──┘
src         └──┘
typ         └──┘
 97    begin simp [mul_succ, right_distrib n m k], sort_add end
id                 └──────┘  └───────────┘      └──────┘
src          └────┘└──────┘└┘└───────────┘     └──────┘
typ          └────┘└──────┘└┘└───────────┘  └──────┘
doc          └────┘        └┘                
txt          └────┘        └┘                
par          └────┘        └┘                  └──────┘
pid                      └┘                
st     └────────────────────────────────────────┘└────────┘└──┘
 98  
 99  protected lemma left_distrib : ∀ (n m k : ℕ), n * (m + k) = n * m + n * k
id                                                             
src                                                                 
typ                                                            
100  | 0        m k := by simp [nat.zero_mul]
id                              └──────────┘
src                       └────┘└──────────┘└┘
typ                       └────┘└──────────┘└┘
doc                       └────┘            └┘
txt                       └────┘            └┘
par                       └────┘            └┘
pid                                       
st                       └───────────────────┘
101  | (succ n) m k :=
id      └──┘
src     └──┘
typ     └──┘
102    begin simp [succ_mul, left_distrib n m k], sort_add end
id                 └──────┘  └──────────┘      └──────┘
src          └────┘└──────┘└┘└──────────┘     └──────┘
typ          └────┘└──────┘└┘└──────────┘  └──────┘
doc          └────┘        └┘               
txt          └────┘        └┘               
par          └────┘        └┘                 └──────┘
pid                      └┘               
st     └───────────────────────────────────────┘└────────┘└──┘
103  
104  protected lemma mul_comm : ∀ (n m : ℕ), n * m = m * n
id                                               
src                                                
typ                                              
105  | n 0        := by rw [nat.zero_mul, nat.mul_zero]
id                          └──────────┘  └──────────┘
src                     └──┘└──────────┘└┘└──────────┘└┘
typ                     └──┘└──────────┘└┘└──────────┘└┘
doc                     └──┘            └┘            └┘
txt                     └──┘            └┘            └┘
par                     └──┘            └┘            └┘
pid                       └┘            └┘            
st                     └───────────────┘└────────────┘
106  | n (succ m) := by simp [mul_succ, succ_mul, mul_comm n m]
id        └──┘                └──────┘  └──────┘  └──────┘  
src       └──┘          └────┘└──────┘└┘└──────┘└┘└──────┘  └─
typ       └──┘          └────┘└──────┘└┘└──────┘└┘└──────┘└─
doc                     └────┘        └┘        └┘          └─
txt                     └────┘        └┘        └┘          └─
par                     └────┘        └┘        └┘          └─
pid                                 └┘        └┘          
st                     └────────────────────────────────────────
107  
src  
typ  
doc  
txt  
par  
pid  
st   
108  protected lemma mul_assoc : ∀ (n m k : ℕ), (n * m) * k = n * (m * k)
id                                                         
src                                                            
typ                                                        
109  | n m 0        := rfl
id                     └─┘
src                    └─┘
typ                    └─┘
110  | n m (succ k) := by simp [mul_succ, nat.left_distrib, mul_assoc n m k]
id          └──┘                └──────┘  └──────────────┘  └───────┘   
src         └──┘          └────┘└──────┘└┘└──────────────┘└┘└───────┘   └─
typ         └──┘          └────┘└──────┘└┘└──────────────┘└┘└───────┘└─
doc                       └────┘        └┘                └┘            └─
txt                       └────┘        └┘                └┘            └─
par                       └────┘        └┘                └┘            └─
pid                                   └┘                └┘            
st                       └───────────────────────────────────────────────────
111  
src  
typ  
doc  
txt  
par  
pid  
st   
112  protected lemma mul_one : ∀ (n : ℕ), n * 1 = n := nat.zero_add
id                                                └──────────┘
src                                                 └──────────┘
typ                                               └──────────┘
113  
114  protected lemma one_mul (n : ℕ) : 1 * n = n :=
id                                         
src                                        
typ                                        
115  by rw [nat.mul_comm, nat.mul_one]
id          └──────────┘  └─────────┘
src     └──┘└──────────┘└┘└─────────┘└─
typ     └──┘└──────────┘└┘└─────────┘└─
doc     └──┘            └┘           └─
txt     └──┘            └┘           └─
par     └──┘            └┘           └─
pid       └┘            └┘           
st     └───────────────┘└───────────┘
116  
src  
typ  
doc  
txt  
par  
pid  
st   
117  instance : comm_semiring nat :=
id              └───────────┘ └─┘
src             └───────────┘ └─┘
typ             └───────────┘ └─┘
118  {add            := nat.add,
id                      └─────┘
src                     └─────┘
typ                     └─────┘
119   add_assoc      := nat.add_assoc,
id                      └───────────┘
src                     └───────────┘
typ                     └───────────┘
120   zero           := nat.zero,
id                      └──────┘
src                     └──────┘
typ                     └──────┘
121   zero_add       := nat.zero_add,
id                      └──────────┘
src                     └──────────┘
typ                     └──────────┘
122   add_zero       := nat.add_zero,
id                      └──────────┘
src                     └──────────┘
typ                     └──────────┘
123   add_comm       := nat.add_comm,
id                      └──────────┘
src                     └──────────┘
typ                     └──────────┘
124   mul            := nat.mul,
id                      └─────┘
src                     └─────┘
typ                     └─────┘
125   mul_assoc      := nat.mul_assoc,
id                      └───────────┘
src                     └───────────┘
typ                     └───────────┘
126   one            := nat.succ nat.zero,
id                      └──────┘ └──────┘
src                     └──────┘ └──────┘
typ                     └──────┘ └──────┘
127   one_mul        := nat.one_mul,
id                      └─────────┘
src                     └─────────┘
typ                     └─────────┘
128   mul_one        := nat.mul_one,
id                      └─────────┘
src                     └─────────┘
typ                     └─────────┘
129   left_distrib   := nat.left_distrib,
id                      └──────────────┘
src                     └──────────────┘
typ                     └──────────────┘
130   right_distrib  := nat.right_distrib,
id                      └───────────────┘
src                     └───────────────┘
typ                     └───────────────┘
131   zero_mul       := nat.zero_mul,
id                      └──────────┘
src                     └──────────┘
typ                     └──────────┘
132   mul_zero       := nat.mul_zero,
id                      └──────────┘
src                     └──────────┘
typ                     └──────────┘
133   mul_comm       := nat.mul_comm}
id                      └──────────┘
src                     └──────────┘
typ                     └──────────┘
134  
135  /- properties of inequality -/
136  
137  protected lemma le_of_eq {n m : ℕ} (p : n = m) : n ≤ m :=
id                                                  
src                                                   
typ                                                 
138  p ▸ less_than_or_equal.refl n
id     └─────────────────────┘ 
src     └─────────────────────┘
typ    └─────────────────────┘ 
139  
140  lemma le_succ_of_le {n m : ℕ} (h : n ≤ m) : n ≤ succ m :=
id                                             └──┘ 
src                                               └──┘
typ                                            └──┘ 
141  nat.le_trans h (le_succ m)
id   └──────────┘   └─────┘ 
src  └──────────┘    └─────┘
typ  └──────────┘   └─────┘ 
142  
143  lemma le_of_succ_le {n m : ℕ} (h : succ n ≤ m) : n ≤ m :=
id                                     └──┘         
src                                    └──┘           
typ                                    └──┘         
144  nat.le_trans (le_succ n) h
id   └──────────┘  └─────┘   
src  └──────────┘  └─────┘
typ  └──────────┘  └─────┘   
145  
146  protected lemma le_of_lt {n m : ℕ} (h : n < m) : n ≤ m :=
id                                                  
src                                                   
typ                                                 
147  le_of_succ_le h
id   └───────────┘ 
src  └───────────┘
typ  └───────────┘ 
148  
149  def lt.step {n m : ℕ} : n < m → n < succ m := less_than_or_equal.step
id                                 └──┘     └─────────────────────┘
src                                   └──┘      └─────────────────────┘
typ                                └──┘     └─────────────────────┘
150  
151  lemma eq_zero_or_pos (n : ℕ) : n = 0 ∨ n > 0 :=
id                                       
src                                        
typ                                      
152  by {cases n, exact or.inl rfl, exact or.inr (succ_pos _)}
id                     └────┘ └─┘        └────┘  └──────┘
src      └────┘   └────┘└────┘└─┘  └────┘└────┘ └──────┘└─┘
typ      └────┘  └────┘└────┘└─┘  └────┘└────┘ └──────┘└─┘
doc      └────┘   └────┘           └────┘               └─┘
txt      └────┘   └────┘           └────┘               └─┘
par      └────┘   └────┘           └────┘               └─┘
pid                                                  └─┘
st     └───────┘└────────────────┘└─────────────────────────┘└┘
153  
154  protected lemma pos_of_ne_zero {n : nat} : n ≠ 0 → n > 0 :=
id                                       └─┘           
src                                      └─┘             
typ                                      └─┘           
155  or.resolve_left (eq_zero_or_pos n)
id   └─────────────┘  └────────────┘ 
src  └─────────────┘  └────────────┘
typ  └─────────────┘  └────────────┘ 
156  
157  protected lemma lt_trans {n m k : ℕ} (h₁ : n < m) : m < k → n < k :=
id                                                          
src                                                             
typ                                                         
158  nat.le_trans (less_than_or_equal.step h₁)
id   └──────────┘  └─────────────────────┘ └┘
src  └──────────┘  └─────────────────────┘
typ  └──────────┘  └─────────────────────┘ └┘
159  
160  protected lemma lt_of_le_of_lt {n m k : ℕ} (h₁ : n ≤ m) : m < k → n < k :=
id                                                                
src                                                                   
typ                                                               
161  nat.le_trans (succ_le_succ h₁)
id   └──────────┘  └──────────┘ └┘
src  └──────────┘  └──────────┘
typ  └──────────┘  └──────────┘ └┘
162  
163  def lt.base (n : ℕ) : n < succ n := nat.le_refl (succ n)
id                          └──┘     └─────────┘  └──┘ 
src                          └──┘      └─────────┘  └──┘
typ                         └──┘     └─────────┘  └──┘ 
164  
165  lemma lt_succ_self (n : ℕ) : n < succ n := lt.base n
id                                 └──┘     └─────┘ 
src                                 └──┘      └─────┘
typ                                └──┘     └─────┘ 
166  
167  protected lemma le_antisymm {n m : ℕ} (h₁ : n ≤ m) : m ≤ n → n = m :=
id                                                           
src                                                              
typ                                                          
168  less_than_or_equal.cases_on h₁ (λ a, rfl) (λ a b c, absurd (nat.lt_of_le_of_lt b c) (nat.lt_irrefl n))
id   └─────────────────────────┘ └┘      └─┘         └────┘  └────────────────┘     └───────────┘ 
src  └─────────────────────────┘          └─┘            └────┘  └────────────────┘       └───────────┘
typ  └─────────────────────────┘ └┘      └─┘         └────┘  └────────────────┘     └───────────┘ 
169  
170  protected lemma lt_or_ge : ∀ (a b : ℕ), a < b ∨ a ≥ b
id                                               
src                                                
typ                                              
171  | a 0     := or.inr (zero_le a)
id               └────┘  └─────┘
src               └────┘  └─────┘
typ              └────┘  └─────┘
172  | a (b+1) :=
id       
src        
typ      
173    match lt_or_ge a b with
id           └──────┘
src          └──────┘
typ          └──────┘
174    | or.inl h := or.inl (le_succ_of_le h)
id       └────┘     └────┘  └───────────┘
src      └────┘      └────┘  └───────────┘
typ      └────┘     └────┘  └───────────┘
175    | or.inr h :=
id       └────┘ 
src      └────┘
typ      └────┘ 
176      match nat.eq_or_lt_of_le h with
id             └────────────────┘
src            └────────────────┘
typ            └────────────────┘
177      | or.inl h1 := or.inl (h1 ▸ lt_succ_self b)
id         └────┘ └┘    └────┘      └──────────┘
src        └────┘       └────┘      └──────────┘
typ        └────┘ └┘    └────┘      └──────────┘
178      | or.inr h1 := or.inr h1
id         └────┘ └┘    └────┘
src        └────┘       └────┘
typ        └────┘ └┘    └────┘
179      end
180    end
181  
182  protected lemma le_total {m n : ℕ} : m ≤ n ∨ n ≤ m :=
id                                             
src                                              
typ                                            
183  or.imp_left nat.le_of_lt (nat.lt_or_ge m n)
id   └─────────┘ └──────────┘  └──────────┘  
src  └─────────┘ └──────────┘  └──────────┘
typ  └─────────┘ └──────────┘  └──────────┘  
184  
185  protected lemma lt_of_le_and_ne {m n : ℕ} (h1 : m ≤ n) : m ≠ n → m < n :=
id                                                               
src                                                                  
typ                                                              
186  or.resolve_right (or.swap (nat.eq_or_lt_of_le h1))
id   └──────────────┘  └─────┘  └────────────────┘ └┘
src  └──────────────┘  └─────┘  └────────────────┘
typ  └──────────────┘  └─────┘  └────────────────┘ └┘
187  
188  protected lemma lt_iff_le_not_le {m n : ℕ} : m < n ↔ (m ≤ n ∧ ¬ n ≤ m) :=
id                                                           
src                                                              
typ                                                          
189  ⟨λ hmn, ⟨nat.le_of_lt hmn, λ hnm, nat.lt_irrefl _ (nat.lt_of_le_of_lt hnm hmn)⟩,
id      └─┘   └──────────┘ └─┘    └─┘  └───────────┘    └────────────────┘ └─┘ └─┘
src           └──────────┘             └───────────┘    └────────────────┘
typ     └─┘   └──────────┘ └─┘    └─┘  └───────────┘    └────────────────┘ └─┘ └─┘
190   λ ⟨hmn, hnm⟩, nat.lt_of_le_and_ne hmn (λ heq, hnm (heq ▸ nat.le_refl _))⟩
id      └─┘  └─┘   └─────────────────┘        └─┘       └─┘  └─────────┘
src                 └─────────────────┘        └─┘       └─┘  └─────────┘
typ     └─┘  └─┘   └─────────────────┘        └─┘       └─┘  └─────────┘
191  
192  instance : linear_order ℕ :=
id              └──────────┘ 
src             └──────────┘ 
typ             └──────────┘ 
193  { le := nat.less_than_or_equal,
id           └────────────────────┘
src          └────────────────────┘
typ          └────────────────────┘
194    le_refl := @nat.le_refl,
id                 └─────────┘
src                └─────────┘
typ                └─────────┘
195    le_trans := @nat.le_trans,
id                  └──────────┘
src                 └──────────┘
typ                 └──────────┘
196    le_antisymm := @nat.le_antisymm,
id                     └─────────────┘
src                    └─────────────┘
typ                    └─────────────┘
197    le_total := @nat.le_total,
id                  └──────────┘
src                 └──────────┘
typ                 └──────────┘
198    lt := nat.lt,
id           └────┘
src          └────┘
typ          └────┘
199    lt_iff_le_not_le := @nat.lt_iff_le_not_le }
id                          └──────────────────┘
src                         └──────────────────┘
typ                         └──────────────────┘
200  
201  lemma eq_zero_of_le_zero {n : nat} (h : n ≤ 0) : n = 0 :=
id                                 └─┘               
src                                └─┘                 
typ                                └─┘               
202  le_antisymm h (zero_le _)
id   └─────────┘   └─────┘
src  └─────────┘    └─────┘
typ  └─────────┘   └─────┘
203  
204  lemma succ_lt_succ {a b : ℕ} : a < b → succ a < succ b :=
id                                      └──┘   └──┘ 
src                                       └──┘    └──┘
typ                                     └──┘   └──┘ 
205  succ_le_succ
id   └──────────┘
src  └──────────┘
typ  └──────────┘
206  
207  lemma lt_of_succ_lt {a b : ℕ} : succ a < b → a < b :=
id                                  └──┘        
src                                 └──┘          
typ                                 └──┘        
208  le_of_succ_le
id   └───────────┘
src  └───────────┘
typ  └───────────┘
209  
210  lemma lt_of_succ_lt_succ {a b : ℕ} : succ a < succ b → a < b :=
id                                       └──┘   └──┘      
src                                      └──┘    └──┘       
typ                                      └──┘   └──┘      
211  le_of_succ_le_succ
id   └────────────────┘
src  └────────────────┘
typ  └────────────────┘
212  
213  lemma pred_lt_pred : ∀ {n m : ℕ}, n ≠ 0 → n < m → pred n < pred m
id                                              └──┘   └──┘ 
src                                                 └──┘    └──┘
typ                                             └──┘   └──┘ 
214  | 0         _       h₁ h := absurd rfl h₁
id                       └┘      └────┘ └─┘
src                              └────┘ └─┘
typ                      └┘      └────┘ └─┘
215  | _         0       h₁ h := absurd h (not_lt_zero _)
id                              └────┘    └─────────┘
src                              └────┘    └─────────┘
typ                             └────┘    └─────────┘
216  | (succ n) (succ m) _  h := lt_of_succ_lt_succ h
id               └──┘           └────────────────┘
src              └──┘            └────────────────┘
typ              └──┘           └────────────────┘
217  
218  lemma lt_of_succ_le {a b : ℕ} (h : succ a ≤ b) : a < b := h
id                                     └──┘             
src                                    └──┘           
typ                                    └──┘             
219  
220  lemma succ_le_of_lt {a b : ℕ} (h : a < b) : succ a ≤ b := h
id                                           └──┘       
src                                            └──┘   
typ                                          └──┘       
221  
222  lemma le_add_right : ∀ (n k : ℕ), n ≤ n + k
id                                       
src                                        
typ                                      
223  | n 0     := nat.le_refl n
id               └─────────┘
src               └─────────┘
typ              └─────────┘
224  | n (k+1) := le_succ_of_le (le_add_right n k)
id             └───────────┘  └──────────┘
src              └───────────┘
typ            └───────────┘  └──────────┘
225  
226  lemma le_add_left (n m : ℕ): n ≤ m + n :=
id                                   
src                                   
typ                                  
227  nat.add_comm n m ▸ le_add_right n m
id   └──────────┘    └──────────┘  
src  └──────────┘      └──────────┘
typ  └──────────┘    └──────────┘  
228  
229  lemma le.dest : ∀ {n m : ℕ}, n ≤ m → ∃ k, n + k = m
id                                         
src                                             
typ                                        
230  | n ._ (less_than_or_equal.refl ._)  := ⟨0, rfl⟩
id           └─────────────────────┘             └─┘
src          └─────────────────────┘             └─┘
typ          └─────────────────────┘             └─┘
231  | n ._ (@less_than_or_equal.step ._ m h) :=
id           └─────────────────────┘      
src           └─────────────────────┘
typ          └─────────────────────┘      
232    match le.dest h with
id           └─────┘
typ          └─────┘
233    | ⟨w, hw⟩ := ⟨succ w, hw ▸ add_succ n w⟩
id          └┘      └──┘        └──────┘
src                  └──┘        └──────┘
typ         └┘      └──┘        └──────┘
234    end
235  
236  lemma le.intro {n m k : ℕ} (h : n + k = m) : n ≤ m :=
id                                            
src                                              
typ                                           
237  h ▸ le_add_right n k
id     └──────────┘  
src     └──────────┘
typ    └──────────┘  
238  
239  protected lemma add_le_add_left {n m : ℕ} (h : n ≤ m) (k : ℕ) : k + n ≤ k + m :=
id                                                                    
src                                                                       
typ                                                                   
240  match le.dest h with
id         └─────┘ 
src        └─────┘
typ        └─────┘ 
241  | ⟨w, hw⟩ := @le.intro _ _ w begin rw [nat.add_assoc, hw] end
id                └──────┘                 └───────────┘  └┘
src                └──────┘             └──┘└───────────┘└┘  └┘
typ               └──────┘             └──┘└───────────┘└┘└┘└┘
doc                                     └──┘             └┘  └┘
txt                                     └──┘             └┘  └┘
par                                     └──┘             └┘  └┘
pid                                       └┘             └┘  
st                                └─────────────────────┘└──┘└─┘
242  end
243  
244  protected lemma add_le_add_right {n m : ℕ} (h : n ≤ m) (k : ℕ) : n + k ≤ m + k :=
id                                                                     
src                                                                        
typ                                                                    
245  begin rw [nat.add_comm n k, nat.add_comm m k], apply nat.add_le_add_left h end
id             └──────────┘    └──────────┘           └─────────────────┘ 
src        └──┘└──────────┘  └┘└──────────┘    └────┘└─────────────────┘ 
typ        └──┘└──────────┘└┘└──────────┘  └────┘└─────────────────┘
doc        └──┘              └┘                └────┘                    
txt        └──┘              └┘                └────┘                    
par        └──┘              └┘                └────┘                    
pid          └┘              └┘                                         
st   └────────────────────────┘└────────────────┘└─────────────────────────────┘└─┘
246  
247  protected lemma le_of_add_le_add_left {k n m : ℕ} (h : k + n ≤ k + m) : n ≤ m :=
id                                                                     
src                                                                        
typ                                                                    
248  match le.dest h with
id         └─────┘ 
src        └─────┘
typ        └─────┘ 
249  | ⟨w, hw⟩ := @le.intro _ _ w
id                └──────┘
src                └──────┘
typ               └──────┘
250    begin
st     └─────
251      rw [nat.add_assoc] at hw,
id           └───────────┘
src      └──┘└───────────┘└─────┘
typ      └──┘└───────────┘└─────┘
doc      └──┘             └─────┘
txt      └──┘             └─────┘
par      └──┘             └─────┘
pid        └┘             └────┘
st   ────────────────────┘└────┘└─
252      apply nat.add_left_cancel hw
id             └─────────────────┘ └┘
src      └────┘└─────────────────┘  
typ      └────┘└─────────────────┘└┘
doc      └────┘                     
txt      └────┘                     
par      └────┘                     
pid                                
st   ─────────────────────────────────
253    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
254  end
255  
256  protected lemma le_of_add_le_add_right {k n m : ℕ} : n + k ≤ m + k → n ≤ m :=
id                                                                  
src                                                                     
typ                                                                 
257  begin
st   └─────
258    rw [nat.add_comm _ k, nat.add_comm _ k],
id         └──────────┘     └──────────┘   
src    └──┘└──────────┘└─┘ └┘└──────────┘└─┘ 
typ    └──┘└──────────┘└─┘└┘└──────────┘└─┘
doc    └──┘            └─┘ └┘            └─┘ 
txt    └──┘            └─┘ └┘            └─┘ 
par    └──┘            └─┘ └┘            └─┘ 
pid      └┘            └─┘ └┘            └─┘ 
st   ─────────────────────┘└────────────────┘└──
259    apply nat.le_of_add_le_add_left
id           └───────────────────────┘
src    └────┘└───────────────────────┘
typ    └────┘└───────────────────────┘
doc    └────┘                         
txt    └────┘                         
par    └────┘                         
pid                                  
st   ─────────────────────────────────┘
260  end
st   └─┘
261  
262  protected lemma add_le_add_iff_le_right (k n m : ℕ) : n + k ≤ m + k ↔ n ≤ m :=
id                                                                  
src                                                                     
typ                                                                 
263    ⟨ nat.le_of_add_le_add_right , assume h, nat.add_le_add_right h _ ⟩
id       └────────────────────────┘            └──────────────────┘ 
src      └────────────────────────┘             └──────────────────┘
typ      └────────────────────────┘            └──────────────────┘ 
264  
265  protected theorem lt_of_add_lt_add_left {k n m : ℕ} (h : k + n < k + m) : n < m :=
id                                                                       
src                                                                          
typ                                                                      
266  let h' := nat.le_of_lt h in
id       └┘    └──────────┘ 
src            └──────────┘
typ      └┘    └──────────┘ 
267  nat.lt_of_le_and_ne
id   └─────────────────┘
src  └─────────────────┘
typ  └─────────────────┘
268    (nat.le_of_add_le_add_left h')
id      └───────────────────────┘ └┘
src     └───────────────────────┘
typ     └───────────────────────┘ └┘
269    (λ heq, nat.lt_irrefl (k + m) begin rw heq at h, assumption end)
id        └─┘  └───────────┘               └─┘
src       └─┘  └───────────┘              └─┘└─┘└───┘  └─────────┘
typ       └─┘  └───────────┘            └─┘└─┘└───┘  └─────────┘
doc                                        └─┘   └───┘  └─────────┘
txt                                        └─┘   └───┘  └─────────┘
par                                        └─┘   └───┘  └─────────┘
pid                                             └───┘            
st                                   └───────────────┘└───────────┘└─┘
270  
271  protected lemma add_lt_add_left {n m : ℕ} (h : n < m) (k : ℕ) : k + n < k + m :=
id                                                                    
src                                                                       
typ                                                                   
272  lt_of_succ_le (add_succ k n ▸ nat.add_le_add_left (succ_le_of_lt h) k)
id   └───────────┘  └──────┘    └─────────────────┘  └───────────┘   
src  └───────────┘  └──────┘      └─────────────────┘  └───────────┘
typ  └───────────┘  └──────┘    └─────────────────┘  └───────────┘   
273  
274  protected lemma add_lt_add_right {n m : ℕ} (h : n < m) (k : ℕ) : n + k < m + k :=
id                                                                     
src                                                                        
typ                                                                    
275  nat.add_comm k m ▸ nat.add_comm k n ▸ nat.add_lt_add_left h k
id   └──────────┘    └──────────┘    └─────────────────┘  
src  └──────────┘      └──────────┘      └─────────────────┘
typ  └──────────┘    └──────────┘    └─────────────────┘  
276  
277  protected lemma lt_add_of_pos_right {n k : ℕ} (h : k > 0) : n < n + k :=
id                                                                
src                                                                 
typ                                                               
278  nat.add_lt_add_left h n
id   └─────────────────┘  
src  └─────────────────┘
typ  └─────────────────┘  
279  
280  protected lemma lt_add_of_pos_left {n k : ℕ} (h : k > 0) : n < k + n :=
id                                                               
src                                                                
typ                                                              
281  by rw add_comm; exact nat.lt_add_of_pos_right h
id         └──────┘        └─────────────────────┘ 
src     └─┘└──────┘  └────┘└─────────────────────┘ 
typ     └─┘└──────┘  └────┘└─────────────────────┘
doc     └─┘          └────┘                        
txt     └─┘          └────┘                        
par     └─┘          └────┘                        
pid                                              
st     └─────────────────────────────────────────────
282  
src  
typ  
doc  
txt  
par  
pid  
st   
283  protected lemma zero_lt_one : 0 < (1:nat) :=
id                                       └─┘
src                                      └─┘
typ                                      └─┘
284  zero_lt_succ 0
id   └──────────┘
src  └──────────┘
typ  └──────────┘
285  
286  lemma mul_le_mul_left {n m : ℕ} (k : ℕ) (h : n ≤ m) : k * n ≤ k * m :=
id                                                          
src                                                             
typ                                                         
287  match le.dest h with
id         └─────┘ 
src        └─────┘
typ        └─────┘ 
288  | ⟨l, hl⟩ :=
id      
typ     
289    have k * n + k * l = k * m, by rw [← left_distrib, hl],
id                                └──────────┘  └┘
src                              └────┘└──────────┘└┘  
typ                         └────┘└──────────┘└┘└┘
doc                                   └────┘            └┘  
txt                                   └────┘            └┘  
par                                   └────┘            └┘  
pid                                     └──┘            └┘  
st                                   └─────────────────┘└──┘
290    le.intro this
id     └──────┘ └──┘
src    └──────┘
typ    └──────┘ └──┘
291  end
292  
293  lemma mul_le_mul_right {n m : ℕ} (k : ℕ) (h : n ≤ m) : n * k ≤ m * k :=
id                                                           
src                                                              
typ                                                          
294  mul_comm k m ▸ mul_comm k n ▸ mul_le_mul_left k h
id   └──────┘    └──────┘    └─────────────┘  
src  └──────┘      └──────┘      └─────────────┘
typ  └──────┘    └──────┘    └─────────────┘  
295  
296  protected lemma mul_lt_mul_of_pos_left {n m k : ℕ} (h : n < m) (hk : k > 0) : k * n < k * m :=
id                                                                                 
src                                                                                     
typ                                                                                
297  nat.lt_of_lt_of_le (nat.lt_add_of_pos_right hk) (mul_succ k n ▸ nat.mul_le_mul_left k (succ_le_of_lt h))
id   └────────────────┘  └─────────────────────┘ └┘   └──────┘    └─────────────────┘   └───────────┘ 
src  └────────────────┘  └─────────────────────┘      └──────┘      └─────────────────┘    └───────────┘
typ  └────────────────┘  └─────────────────────┘ └┘   └──────┘    └─────────────────┘   └───────────┘ 
298  
299  protected lemma mul_lt_mul_of_pos_right {n m k : ℕ} (h : n < m) (hk : k > 0) : n * k < m * k :=
id                                                                                  
src                                                                                      
typ                                                                                 
300  mul_comm k m ▸ mul_comm k n ▸ nat.mul_lt_mul_of_pos_left h hk
id   └──────┘    └──────┘    └────────────────────────┘  └┘
src  └──────┘      └──────┘      └────────────────────────┘
typ  └──────┘    └──────┘    └────────────────────────┘  └┘
301  
302  instance : decidable_linear_ordered_semiring nat :=
id              └───────────────────────────────┘ └─┘
src             └───────────────────────────────┘ └─┘
typ             └───────────────────────────────┘ └─┘
303  { add_left_cancel            := @nat.add_left_cancel,
id                                    └─────────────────┘
src                                   └─────────────────┘
typ                                   └─────────────────┘
304    add_right_cancel           := @nat.add_right_cancel,
id                                    └──────────────────┘
src                                   └──────────────────┘
typ                                   └──────────────────┘
305    lt                         := nat.lt,
id                                   └────┘
src                                  └────┘
typ                                  └────┘
306    le                         := nat.le,
id                                   └────┘
src                                  └────┘
typ                                  └────┘
307    le_refl                    := nat.le_refl,
id                                   └─────────┘
src                                  └─────────┘
typ                                  └─────────┘
308    le_trans                   := @nat.le_trans,
id                                    └──────────┘
src                                   └──────────┘
typ                                   └──────────┘
309    le_antisymm                := @nat.le_antisymm,
id                                    └─────────────┘
src                                   └─────────────┘
typ                                   └─────────────┘
310    le_total                   := @nat.le_total,
id                                    └──────────┘
src                                   └──────────┘
typ                                   └──────────┘
311    lt_iff_le_not_le           := @lt_iff_le_not_le _ _,
id                                    └──────────────┘
src                                   └──────────────┘
typ                                   └──────────────┘
312    add_le_add_left            := @nat.add_le_add_left,
id                                    └─────────────────┘
src                                   └─────────────────┘
typ                                   └─────────────────┘
313    le_of_add_le_add_left      := @nat.le_of_add_le_add_left,
id                                    └───────────────────────┘
src                                   └───────────────────────┘
typ                                   └───────────────────────┘
314    zero_lt_one                := zero_lt_succ 0,
id                                   └──────────┘
src                                  └──────────┘
typ                                  └──────────┘
315    mul_le_mul_of_nonneg_left  := assume a b c h₁ h₂, nat.mul_le_mul_left c h₁,
id                                             └┘ └┘  └─────────────────┘  └┘
src                                                      └─────────────────┘
typ                                            └┘ └┘  └─────────────────┘  └┘
316    mul_le_mul_of_nonneg_right := assume a b c h₁ h₂, nat.mul_le_mul_right c h₁,
id                                             └┘ └┘  └──────────────────┘  └┘
src                                                      └──────────────────┘
typ                                            └┘ └┘  └──────────────────┘  └┘
317    mul_lt_mul_of_pos_left     := @nat.mul_lt_mul_of_pos_left,
id                                    └────────────────────────┘
src                                   └────────────────────────┘
typ                                   └────────────────────────┘
318    mul_lt_mul_of_pos_right    := @nat.mul_lt_mul_of_pos_right,
id                                    └─────────────────────────┘
src                                   └─────────────────────────┘
typ                                   └─────────────────────────┘
319    decidable_lt               := nat.decidable_lt,
id                                   └──────────────┘
src                                  └──────────────┘
typ                                  └──────────────┘
320    decidable_le               := nat.decidable_le,
id                                   └──────────────┘
src                                  └──────────────┘
typ                                  └──────────────┘
321    decidable_eq               := nat.decidable_eq,
id                                   └──────────────┘
src                                  └──────────────┘
typ                                  └──────────────┘
322    ..nat.comm_semiring }
id       └───────────────┘
src      └───────────────┘
typ      └───────────────┘
323  
324  -- all the fields are already included in the decidable_linear_ordered_semiring instance
325  instance : decidable_linear_ordered_cancel_comm_monoid ℕ :=
id              └─────────────────────────────────────────┘ 
src             └─────────────────────────────────────────┘ 
typ             └─────────────────────────────────────────┘ 
326  { add_left_cancel := @nat.add_left_cancel,
id                         └─────────────────┘
src                        └─────────────────┘
typ                        └─────────────────┘
327    ..nat.decidable_linear_ordered_semiring }
id       └───────────────────────────────────┘
src      └───────────────────────────────────┘
typ      └───────────────────────────────────┘
328  
329  lemma le_of_lt_succ {m n : nat} : m < succ n → m ≤ n :=
id                              └─┘      └──┘      
src                             └─┘       └──┘       
typ                             └─┘      └──┘      
330  le_of_succ_le_succ
id   └────────────────┘
src  └────────────────┘
typ  └────────────────┘
331  
332  theorem eq_of_mul_eq_mul_left {m k n : ℕ} (Hn : n > 0) (H : n * m = n * k) : m = k :=
id                                                                        
src                                                                            
typ                                                                       
333  le_antisymm (le_of_mul_le_mul_left (le_of_eq H) Hn)
id   └─────────┘  └───────────────────┘  └──────┘   └┘
src  └─────────┘  └───────────────────┘  └──────┘
typ  └─────────┘  └───────────────────┘  └──────┘   └┘
334              (le_of_mul_le_mul_left (le_of_eq H.symm) Hn)
id                └───────────────────┘  └──────┘ └───┘  └┘
src               └───────────────────┘  └──────┘  └───┘
typ               └───────────────────┘  └──────┘ └───┘  └┘
335  
336  theorem eq_of_mul_eq_mul_right {n m k : ℕ} (Hm : m > 0) (H : n * m = k * m) : n = k :=
id                                                                         
src                                                                             
typ                                                                        
337  by rw [mul_comm n m, mul_comm k m] at H; exact eq_of_mul_eq_mul_left Hm H
id          └──────┘    └──────┘                └───────────────────┘ └┘ 
src     └──┘└──────┘  └┘└──────┘  └────┘  └────┘└───────────────────┘   
typ     └──┘└──────┘└┘└──────┘└────┘  └────┘└───────────────────┘└┘
doc     └──┘          └┘          └────┘  └────┘                        
txt     └──┘          └┘          └────┘  └────┘                        
par     └──┘          └┘          └────┘  └────┘                        
pid       └┘          └┘          └───┘                               
st     └───────────────┘└────────────┘└───────────────────────────────────────
338  
src  
typ  
doc  
txt  
par  
pid  
st   
339  /- sub properties -/
src  ─────────────────────
typ  ─────────────────────
doc  ─────────────────────
txt  ─────────────────────
par  ─────────────────────
pid  ─────────────────────
st   ─────────────────────
340  
src  
typ  
doc  
txt  
par  
pid  
st   
341  @[simp] protected lemma zero_sub : ∀ a : ℕ, 0 - a = 0
id                                                 
src                                                 
typ                                                
doc    └──┘
342  | 0     := rfl
id              └─┘
src             └─┘
typ             └─┘
343  | (a+1) := congr_arg pred (zero_sub a)
id            └───────┘ └──┘  └──────┘
src            └───────┘ └──┘  └──────┘
typ           └───────┘ └──┘  └──────┘
344  
345  lemma sub_lt_succ (a b : ℕ) : a - b < succ a :=
id                                    └──┘ 
src                                     └──┘
typ                                   └──┘ 
346  lt_succ_of_le (sub_le a b)
id   └───────────┘  └────┘  
src  └───────────┘  └────┘
typ  └───────────┘  └────┘  
347  
348  protected theorem sub_le_sub_right {n m : ℕ} (h : n ≤ m) : ∀ k, n - k ≤ m - k
id                                                                    
src                                                                       
typ                                                                   
349  | 0        := h
id                 
typ                
350  | (succ z) := pred_le_pred (sub_le_sub_right z)
id      └──┘      └──────────┘  └──────────────┘
src     └──┘       └──────────┘  └──────────────┘
typ     └──┘      └──────────┘  └──────────────┘
351  
352  /- bit0/bit1 properties -/
353  
354  protected lemma bit1_eq_succ_bit0 (n : ℕ) : bit1 n = succ (bit0 n) :=
id                                              └──┘   └──┘  └──┘ 
src                                             └──┘    └──┘  └──┘
typ                                             └──┘   └──┘  └──┘ 
355  rfl
id   └─┘
src  └─┘
typ  └─┘
356  
357  protected lemma bit1_succ_eq (n : ℕ) : bit1 (succ n) = succ (succ (bit1 n)) :=
id                                         └──┘  └──┘    └──┘  └──┘  └──┘ 
src                                        └──┘  └──┘     └──┘  └──┘  └──┘
typ                                        └──┘  └──┘    └──┘  └──┘  └──┘ 
358  eq.trans (nat.bit1_eq_succ_bit0 (succ n)) (congr_arg succ (nat.bit0_succ_eq n))
id   └──────┘  └───────────────────┘  └──┘     └───────┘ └──┘  └──────────────┘ 
src  └──────┘  └───────────────────┘  └──┘      └───────┘ └──┘  └──────────────┘
typ  └──────┘  └───────────────────┘  └──┘     └───────┘ └──┘  └──────────────┘ 
359  
360  protected lemma bit1_ne_one : ∀ {n : ℕ}, n ≠ 0 → bit1 n ≠ 1
id                                                └──┘  
src                                                 └──┘   
typ                                               └──┘  
361  | 0     h h1 := absurd rfl h
id                  └────┘ └─┘
src                  └────┘ └─┘
typ                 └────┘ └─┘
362  | (n+1) h h1 := nat.no_confusion h1 (λ h2, absurd h2 (succ_ne_zero _))
id            └┘    └──────────────┘       └┘  └────┘ └┘  └──────────┘
src                 └──────────────┘           └────┘     └──────────┘
typ           └┘    └──────────────┘       └┘  └────┘ └┘  └──────────┘
363  
364  protected lemma bit0_ne_one : ∀ n : ℕ, bit0 n ≠ 1
id                                        └──┘  
src                                        └──┘   
typ                                       └──┘  
365  | 0     h := absurd h (ne.symm nat.one_ne_zero)
id               └────┘    └─────┘ └─────────────┘
src               └────┘    └─────┘ └─────────────┘
typ              └────┘    └─────┘ └─────────────┘
366  | (n+1) h :=
id         
src      
typ        
367    have h1 : succ (succ (n + n)) = 1, from succ_add n n ▸ h,
id               └──┘  └──┘                  └──────┘     
src              └──┘  └──┘                  └──────┘     
typ              └──┘  └──┘                  └──────┘     
368    nat.no_confusion h1
id     └──────────────┘ └┘
src    └──────────────┘
typ    └──────────────┘ └┘
369      (λ h2, absurd h2 (succ_ne_zero (n + n)))
id          └┘  └────┘ └┘  └──────────┘    
src             └────┘     └──────────┘    
typ         └┘  └────┘ └┘  └──────────┘    
370  
371  protected lemma add_self_ne_one : ∀ (n : ℕ), n + n ≠ 1
id                                                 
src                                                   
typ                                                
372  | 0     h := nat.no_confusion h
id               └──────────────┘
src               └──────────────┘
typ              └──────────────┘
373  | (n+1) h :=
id         
src      
typ        
374    have h1 : succ (succ (n + n)) = 1, from succ_add n n ▸ h,
id               └──┘  └──┘                  └──────┘     
src              └──┘  └──┘                  └──────┘     
typ              └──┘  └──┘                  └──────┘     
375    nat.no_confusion h1 (λ h2, absurd h2 (nat.succ_ne_zero (n + n)))
id     └──────────────┘ └┘    └┘  └────┘ └┘  └──────────────┘    
src    └──────────────┘           └────┘     └──────────────┘    
typ    └──────────────┘ └┘    └┘  └────┘ └┘  └──────────────┘    
376  
377  protected lemma bit1_ne_bit0 : ∀ (n m : ℕ), bit1 n ≠ bit0 m
id                                             └──┘   └──┘ 
src                                             └──┘    └──┘
typ                                            └──┘   └──┘ 
378  | 0     m     h := absurd h (ne.symm (nat.add_self_ne_one m))
id                    └────┘    └─────┘  └─────────────────┘
src                     └────┘    └─────┘  └─────────────────┘
typ                   └────┘    └─────┘  └─────────────────┘
379  | (n+1) 0     h :=
id               
src      
typ              
380    have h1 : succ (bit0 (succ n)) = 0, from h,
id               └──┘  └──┘  └──┘     
src              └──┘  └──┘  └──┘     
typ              └──┘  └──┘  └──┘     
381    absurd h1 (nat.succ_ne_zero _)
id     └────┘ └┘  └──────────────┘
src    └────┘     └──────────────┘
typ    └────┘ └┘  └──────────────┘
382  | (n+1) (m+1) h :=
id             
src           
typ            
383    have h1 : succ (succ (bit1 n)) = succ (succ (bit0 m)), from
id               └──┘  └──┘  └──┘      └──┘  └──┘  └──┘
src              └──┘  └──┘  └──┘      └──┘  └──┘  └──┘
typ              └──┘  └──┘  └──┘      └──┘  └──┘  └──┘
384      nat.bit0_succ_eq m ▸ nat.bit1_succ_eq n ▸ h,
id       └──────────────┘    └──────────────┘   
src      └──────────────┘    └──────────────┘   
typ      └──────────────┘    └──────────────┘   
385    have h2 : bit1 n = bit0 m, from
id               └──┘    └──┘
src              └──┘    └──┘
typ              └──┘    └──┘
386      nat.no_confusion h1 (λ h2', nat.no_confusion h2' (λ h2'', h2'')),
id       └──────────────┘ └┘    └─┘  └──────────────┘ └─┘    └──┘  └──┘
src      └──────────────┘            └──────────────┘
typ      └──────────────┘ └┘    └─┘  └──────────────┘ └─┘    └──┘  └──┘
387    absurd h2 (bit1_ne_bit0 n m)
id     └────┘ └┘  └──────────┘
src    └────┘
typ    └────┘ └┘  └──────────┘
388  
389  protected lemma bit0_ne_bit1 : ∀ (n m : ℕ), bit0 n ≠ bit1 m :=
id                                              └──┘   └──┘ 
src                                             └──┘    └──┘
typ                                             └──┘   └──┘ 
390  λ n m : nat, ne.symm (nat.bit1_ne_bit0 m n)
id           └─┘  └─────┘  └──────────────┘  
src          └─┘  └─────┘  └──────────────┘
typ          └─┘  └─────┘  └──────────────┘  
391  
392  protected lemma bit0_inj : ∀ {n m : ℕ}, bit0 n = bit0 m → n = m
id                                         └──┘   └──┘      
src                                         └──┘    └──┘       
typ                                        └──┘   └──┘      
393  | 0     0     h := rfl
id                      └─┘
src                     └─┘
typ                     └─┘
394  | 0     (m+1) h := by contradiction
id             
src                       └────────────┘
typ                       └────────────┘
doc                        └────────────┘
txt                        └────────────┘
par                        └────────────┘
pid                                     
st                        └─────────────┘
395  | (n+1) 0     h := by contradiction
id       
src                       └────────────┘
typ                       └────────────┘
doc                        └────────────┘
txt                        └────────────┘
par                        └────────────┘
pid                                     
st                        └─────────────┘
396  | (n+1) (m+1) h :=
id          
src           
typ         
397    have succ (succ (n + n)) = succ (succ (m + m)),
id          └──┘  └──┘          └──┘  └──┘    
src         └──┘  └──┘          └──┘  └──┘    
typ         └──┘  └──┘          └──┘  └──┘    
398    begin unfold bit0 at h, simp [add_one, add_succ, succ_add] at h, rw h end,
id                                   └─────┘  └──────┘  └──────┘           
src          └──────────────┘  └────┘└─────┘└┘└──────┘└┘└──────┘└────┘  └─┘ 
typ          └──────────────┘  └────┘└─────┘└┘└──────┘└┘└──────┘└────┘  └─┘
doc          └──────────────┘  └────┘       └┘        └┘        └────┘  └─┘ 
txt          └──────────────┘  └────┘       └┘        └┘        └────┘  └─┘ 
par          └──────────────┘  └────┘       └┘        └┘        └────┘  └─┘ 
pid                └───┘└───┘             └┘        └┘        └──┘     
st     └────────────────────┘└───────────────────────────────────────┘└─────┘└─┘
399    have n + n = m + m, by iterate { injection this with this },
id                                             └──┘
src                        └────────┘└────────┘    └─────────┘
typ                        └────────┘└────────┘└──┘└─────────┘
doc                           └────────┘└────────┘    └─────────┘
txt                           └────────┘└────────┘    └─────────┘
par                           └────────┘└────────┘    └─────────┘
pid                                  └──────────┘    └──────────┘
st                           └──────────────────────────────────┘└┘
400    have n = m, from bit0_inj this,
id                     └──────┘ └──┘
src           
typ                    └──────┘ └──┘
401    by rw this
id           └──┘
src       └─┘    
typ       └─┘└──┘
doc       └─┘    
txt       └─┘    
par       └─┘    
pid             
st       └────────
402  
src  
typ  
doc  
txt  
par  
pid  
st   
403  protected lemma bit1_inj : ∀ {n m : ℕ}, bit1 n = bit1 m → n = m :=
id                                          └──┘   └──┘      
src                                         └──┘    └──┘       
typ                                         └──┘   └──┘      
404  λ n m h,
id       
typ      
405  have succ (bit0 n) = succ (bit0 m), begin simp [nat.bit1_eq_succ_bit0] at h, rw h end,
id        └──┘  └──┘    └──┘  └──┘                └───────────────────┘           
src       └──┘  └──┘     └──┘  └──┘           └────┘└───────────────────┘└────┘  └─┘ 
typ       └──┘  └──┘    └──┘  └──┘          └────┘└───────────────────┘└────┘  └─┘
doc                                            └────┘                     └────┘  └─┘ 
txt                                            └────┘                     └────┘  └─┘ 
par                                            └────┘                     └────┘  └─┘ 
pid                                                                     └──┘     
st                                       └─────────────────────────────────────┘└─────┘└─┘
406  have bit0 n = bit0 m, by injection this,
id        └──┘   └──┘                └──┘
src       └──┘    └──┘       └────────┘
typ       └──┘   └──┘      └────────┘└──┘
doc                           └────────┘
txt                           └────────┘
par                           └────────┘
pid                                    
st                           └─────────────┘
407  nat.bit0_inj this
id   └──────────┘ └──┘
src  └──────────┘
typ  └──────────┘ └──┘
408  
409  protected lemma bit0_ne {n m : ℕ} : n ≠ m → bit0 n ≠ bit0 m :=
id                                           └──┘   └──┘ 
src                                            └──┘    └──┘
typ                                          └──┘   └──┘ 
410  λ h₁ h₂, absurd (nat.bit0_inj h₂) h₁
id     └┘ └┘  └────┘  └──────────┘ └┘  └┘
src           └────┘  └──────────┘
typ    └┘ └┘  └────┘  └──────────┘ └┘  └┘
411  
412  protected lemma bit1_ne {n m : ℕ} : n ≠ m → bit1 n ≠ bit1 m :=
id                                           └──┘   └──┘ 
src                                            └──┘    └──┘
typ                                          └──┘   └──┘ 
413  λ h₁ h₂, absurd (nat.bit1_inj h₂) h₁
id     └┘ └┘  └────┘  └──────────┘ └┘  └┘
src           └────┘  └──────────┘
typ    └┘ └┘  └────┘  └──────────┘ └┘  └┘
414  
415  protected lemma zero_ne_bit0 {n : ℕ} : n ≠ 0 → 0 ≠ bit0 n :=
id                                                  └──┘ 
src                                                  └──┘
typ                                                 └──┘ 
416  λ h, ne.symm (nat.bit0_ne_zero h)
id       └─────┘  └──────────────┘ 
src       └─────┘  └──────────────┘
typ      └─────┘  └──────────────┘ 
417  
418  protected lemma zero_ne_bit1 (n : ℕ) : 0 ≠ bit1 n :=
id                                            └──┘ 
src                                           └──┘
typ                                           └──┘ 
419  ne.symm (nat.bit1_ne_zero n)
id   └─────┘  └──────────────┘ 
src  └─────┘  └──────────────┘
typ  └─────┘  └──────────────┘ 
420  
421  protected lemma one_ne_bit0 (n : ℕ) : 1 ≠ bit0 n :=
id                                           └──┘ 
src                                          └──┘
typ                                          └──┘ 
422  ne.symm (nat.bit0_ne_one n)
id   └─────┘  └─────────────┘ 
src  └─────┘  └─────────────┘
typ  └─────┘  └─────────────┘ 
423  
424  protected lemma one_ne_bit1 {n : ℕ} : n ≠ 0 → 1 ≠ bit1 n :=
id                                                 └──┘ 
src                                                 └──┘
typ                                                └──┘ 
425  λ h, ne.symm (nat.bit1_ne_one h)
id       └─────┘  └─────────────┘ 
src       └─────┘  └─────────────┘
typ      └─────┘  └─────────────┘ 
426  
427  protected lemma one_lt_bit1 : ∀ {n : nat}, n ≠ 0 → 1 < bit1 n
id                                       └─┘            └──┘ 
src                                       └─┘             └──┘
typ                                      └─┘            └──┘ 
428  | 0        h := by contradiction
src                     └────────────┘
typ                     └────────────┘
doc                     └────────────┘
txt                     └────────────┘
par                     └────────────┘
pid                                  
st                     └─────────────┘
429  | (succ n) h :=
id      └──┘
src     └──┘
typ     └──┘
430    begin
st     └─────
431      rw nat.bit1_succ_eq,
id          └──────────────┘
src      └─┘└──────────────┘
typ      └─┘└──────────────┘
doc      └─┘
txt      └─┘
par      └─┘
pid        
st   ──────────────────────┘└─
432      apply succ_lt_succ,
id             └──────────┘
src      └────┘└──────────┘
typ      └────┘└──────────┘
doc      └────┘
txt      └────┘
par      └────┘
pid           
st   ─────────────────────┘└─
433      apply zero_lt_succ
id             └──────────┘
src      └────┘└──────────┘
typ      └────┘└──────────┘
doc      └────┘            
txt      └────┘            
par      └────┘            
pid                       
st   ───────────────────────
434    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
435  
436  protected lemma one_lt_bit0 : ∀ {n : nat}, n ≠ 0 → 1 < bit0 n
id                                       └─┘            └──┘ 
src                                       └─┘             └──┘
typ                                      └─┘            └──┘ 
437  | 0        h := by contradiction
src                     └────────────┘
typ                     └────────────┘
doc                     └────────────┘
txt                     └────────────┘
par                     └────────────┘
pid                                  
st                     └─────────────┘
438  | (succ n) h :=
id      └──┘
src     └──┘
typ     └──┘
439    begin
st     └─────
440      rw nat.bit0_succ_eq,
id          └──────────────┘
src      └─┘└──────────────┘
typ      └─┘└──────────────┘
doc      └─┘
txt      └─┘
par      └─┘
pid        
st   ──────────────────────┘└─
441      apply succ_lt_succ,
id             └──────────┘
src      └────┘└──────────┘
typ      └────┘└──────────┘
doc      └────┘
txt      └────┘
par      └────┘
pid           
st   ─────────────────────┘└─
442      apply zero_lt_succ
id             └──────────┘
src      └────┘└──────────┘
typ      └────┘└──────────┘
doc      └────┘            
txt      └────┘            
par      └────┘            
pid                       
st   ───────────────────────
443    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
444  
445  protected lemma bit0_lt {n m : nat} (h : n < m) : bit0 n < bit0 m :=
id                                  └─┘             └──┘   └──┘ 
src                                 └─┘               └──┘    └──┘
typ                                 └─┘             └──┘   └──┘ 
446  add_lt_add h h
id   └────────┘  
src  └────────┘
typ  └────────┘  
447  
448  protected lemma bit1_lt {n m : nat} (h : n < m) : bit1 n < bit1 m :=
id                                  └─┘             └──┘   └──┘ 
src                                 └─┘               └──┘    └──┘
typ                                 └─┘             └──┘   └──┘ 
449  succ_lt_succ (add_lt_add h h)
id   └──────────┘  └────────┘  
src  └──────────┘  └────────┘
typ  └──────────┘  └────────┘  
450  
451  protected lemma bit0_lt_bit1 {n m : nat} (h : n ≤ m) : bit0 n < bit1 m :=
id                                       └─┘             └──┘   └──┘ 
src                                      └─┘               └──┘    └──┘
typ                                      └─┘             └──┘   └──┘ 
452  lt_succ_of_le (add_le_add h h)
id   └───────────┘  └────────┘  
src  └───────────┘  └────────┘
typ  └───────────┘  └────────┘  
453  
454  protected lemma bit1_lt_bit0 : ∀ {n m : nat}, n < m → bit1 n < bit0 m
id                                          └─┘        └──┘   └──┘ 
src                                          └─┘          └──┘    └──┘
typ                                         └─┘        └──┘   └──┘ 
455  | n 0        h := absurd h (not_lt_zero _)
id                    └────┘    └─────────┘
src                    └────┘    └─────────┘
typ                   └────┘    └─────────┘
456  | n (succ m) h :=
id       └──┘   
src       └──┘
typ      └──┘   
457    have n ≤ m, from le_of_lt_succ h,
id                     └───────────┘
src                    └───────────┘
typ                    └───────────┘
458    have succ (n + n) ≤ succ (m + m), from succ_le_succ (add_le_add this this),
id          └──┘         └──┘              └──────────┘  └────────┘ └──┘ └──┘
src         └──┘         └──┘              └──────────┘  └────────┘
typ         └──┘         └──┘              └──────────┘  └────────┘ └──┘ └──┘
459    have succ (n + n) ≤ succ m + m, {rw succ_add, assumption},
id          └──┘         └──┘           └──────┘
src         └──┘         └──┘        └─┘└──────┘  └────────┘
typ         └──┘         └──┘        └─┘└──────┘  └────────┘
doc                                     └─┘          └────────┘
txt                                     └─┘          └────────┘
par                                     └─┘          └────────┘
pid                                       
st                                     └──────────┘└──────────┘└┘
460    show succ (n + n) < succ (succ m + m), from lt_succ_of_le this
id          └──┘         └──┘  └──┘             └───────────┘ └──┘
src         └──┘         └──┘  └──┘             └───────────┘
typ         └──┘         └──┘  └──┘             └───────────┘ └──┘
461  
462  protected lemma one_le_bit1 (n : ℕ) : 1 ≤ bit1 n :=
id                                           └──┘ 
src                                          └──┘
typ                                          └──┘ 
463  show 1 ≤ succ (bit0 n), from
id           └──┘  └──┘ 
src          └──┘  └──┘
typ          └──┘  └──┘ 
464  succ_le_succ (zero_le (bit0 n))
id   └──────────┘  └─────┘  └──┘ 
src  └──────────┘  └─────┘  └──┘
typ  └──────────┘  └─────┘  └──┘ 
465  
466  protected lemma one_le_bit0 : ∀ (n : ℕ), n ≠ 0 → 1 ≤ bit0 n
id                                                   └──┘ 
src                                                    └──┘
typ                                                  └──┘ 
467  | 0     h := absurd rfl h
id               └────┘ └─┘
src               └────┘ └─┘
typ              └────┘ └─┘
468  | (n+1) h :=
id      
src      
typ     
469    suffices 1 ≤ succ (succ (bit0 n)), from
id                 └──┘  └──┘  └──┘
src                └──┘  └──┘  └──┘
typ                └──┘  └──┘  └──┘
470      eq.symm (nat.bit0_succ_eq n) ▸ this,
id       └─────┘  └──────────────┘     └──┘
src      └─────┘  └──────────────┘    
typ      └─────┘  └──────────────┘     └──┘
471    succ_le_succ (zero_le (succ (bit0 n)))
id     └──────────┘  └─────┘  └──┘  └──┘
src    └──────────┘  └─────┘  └──┘  └──┘
typ    └──────────┘  └─────┘  └──┘  └──┘
472  
473  /- Extra instances to short-circuit type class resolution -/
474  instance : add_comm_monoid nat    := by apply_instance
id              └─────────────┘ └─┘
src             └─────────────┘ └─┘          └─────────────┘
typ             └─────────────┘ └─┘          └─────────────┘
doc                                          └─────────────┘
txt                                          └─────────────┘
par                                          └─────────────┘
pid                                                        
st                                          └──────────────┘
475  instance : add_monoid nat         := by apply_instance
id              └────────┘ └─┘
src             └────────┘ └─┘               └─────────────┘
typ             └────────┘ └─┘               └─────────────┘
doc                                          └─────────────┘
txt                                          └─────────────┘
par                                          └─────────────┘
pid                                                        
st                                          └──────────────┘
476  instance : monoid nat             := by apply_instance
id              └────┘ └─┘
src             └────┘ └─┘                   └─────────────┘
typ             └────┘ └─┘                   └─────────────┘
doc                                          └─────────────┘
txt                                          └─────────────┘
par                                          └─────────────┘
pid                                                        
st                                          └──────────────┘
477  instance : comm_monoid nat        := by apply_instance
id              └─────────┘ └─┘
src             └─────────┘ └─┘              └─────────────┘
typ             └─────────┘ └─┘              └─────────────┘
doc                                          └─────────────┘
txt                                          └─────────────┘
par                                          └─────────────┘
pid                                                        
st                                          └──────────────┘
478  instance : comm_semigroup nat     := by apply_instance
id              └────────────┘ └─┘
src             └────────────┘ └─┘           └─────────────┘
typ             └────────────┘ └─┘           └─────────────┘
doc                                          └─────────────┘
txt                                          └─────────────┘
par                                          └─────────────┘
pid                                                        
st                                          └──────────────┘
479  instance : semigroup nat          := by apply_instance
id              └───────┘ └─┘
src             └───────┘ └─┘                └─────────────┘
typ             └───────┘ └─┘                └─────────────┘
doc                                          └─────────────┘
txt                                          └─────────────┘
par                                          └─────────────┘
pid                                                        
st                                          └──────────────┘
480  instance : add_comm_semigroup nat := by apply_instance
id              └────────────────┘ └─┘
src             └────────────────┘ └─┘       └─────────────┘
typ             └────────────────┘ └─┘       └─────────────┘
doc                                          └─────────────┘
txt                                          └─────────────┘
par                                          └─────────────┘
pid                                                        
st                                          └──────────────┘
481  instance : add_semigroup nat      := by apply_instance
id              └───────────┘ └─┘
src             └───────────┘ └─┘            └─────────────┘
typ             └───────────┘ └─┘            └─────────────┘
doc                                          └─────────────┘
txt                                          └─────────────┘
par                                          └─────────────┘
pid                                                        
st                                          └──────────────┘
482  instance : distrib nat            := by apply_instance
id              └─────┘ └─┘
src             └─────┘ └─┘                  └─────────────┘
typ             └─────┘ └─┘                  └─────────────┘
doc                                          └─────────────┘
txt                                          └─────────────┘
par                                          └─────────────┘
pid                                                        
st                                          └──────────────┘
483  instance : semiring nat           := by apply_instance
id              └──────┘ └─┘
src             └──────┘ └─┘                 └─────────────┘
typ             └──────┘ └─┘                 └─────────────┘
doc                                          └─────────────┘
txt                                          └─────────────┘
par                                          └─────────────┘
pid                                                        
st                                          └──────────────┘
484  instance : ordered_semiring nat   := by apply_instance
id              └──────────────┘ └─┘
src             └──────────────┘ └─┘         └──────────────
typ             └──────────────┘ └─┘         └──────────────
doc                                          └──────────────
txt                                          └──────────────
par                                          └──────────────
pid                                                        
st                                          └───────────────
485  
src  
typ  
doc  
txt  
par  
pid  
st   
486  /- subtraction -/
src  ─────────────────┘
typ  ─────────────────┘
doc  ─────────────────┘
txt  ─────────────────┘
par  ─────────────────┘
pid  ─────────────────┘
st   ─────────────────┘
487  @[simp]
doc    └──┘
488  protected theorem sub_zero (n : ℕ) : n - 0 = n :=
id                                            
src                                           
typ                                           
489  rfl
id   └─┘
src  └─┘
typ  └─┘
490  
491  theorem sub_succ (n m : ℕ) : n - succ m = pred (n - m) :=
id                                 └──┘   └──┘    
src                                 └──┘    └──┘    
typ                                └──┘   └──┘    
492  rfl
id   └─┘
src  └─┘
typ  └─┘
493  
494  theorem succ_sub_succ (n m : ℕ) : succ n - succ m = n - m :=
id                                    └──┘   └──┘     
src                                   └──┘    └──┘      
typ                                   └──┘   └──┘     
495  succ_sub_succ_eq_sub n m
id   └──────────────────┘  
src  └──────────────────┘
typ  └──────────────────┘  
496  
497  protected theorem sub_self : ∀ (n : ℕ), n - n = 0
id                                            
src                                             
typ                                           
498  | 0        := by rw nat.sub_zero
id                       └──────────┘
src                   └─┘└──────────┘
typ                   └─┘└──────────┘
doc                   └─┘            
txt                   └─┘            
par                   └─┘            
pid                                 
st                   └───────────────┘
499  | (succ n) := by rw [succ_sub_succ, sub_self n]
id      └──┘              └───────────┘  └──────┘ 
src     └──┘          └──┘└───────────┘└┘└──────┘ └─
typ     └──┘          └──┘└───────────┘└┘└──────┘└─
doc                   └──┘             └┘         └─
txt                   └──┘             └┘         └─
par                   └──┘             └┘         └─
pid                     └┘             └┘         
st                   └────────────────┘└──────────┘
500  
src  
typ  
doc  
txt  
par  
pid  
st   
501  /- TODO(Leo): remove the following ematch annotations as soon as we have
src  ─────────────────────────────────────────────────────────────────────────
typ  ─────────────────────────────────────────────────────────────────────────
doc  ─────────────────────────────────────────────────────────────────────────
txt  ─────────────────────────────────────────────────────────────────────────
par  ─────────────────────────────────────────────────────────────────────────
pid  ─────────────────────────────────────────────────────────────────────────
st   ─────────────────────────────────────────────────────────────────────────
502     arithmetic theory in the smt_stactic -/
src  ──────────────────────────────────────────┘
typ  ──────────────────────────────────────────┘
doc  ──────────────────────────────────────────┘
txt  ──────────────────────────────────────────┘
par  ──────────────────────────────────────────┘
pid  ──────────────────────────────────────────┘
st   ──────────────────────────────────────────┘
503  @[ematch_lhs]
src    └────────┘
doc    └────────┘
504  protected theorem add_sub_add_right : ∀ (n k m : ℕ), (n + k) - (m + k) = n - m
id                                                                    
src                                                                        
typ                                                                   
505  | n 0        m := by rw [add_zero, add_zero]
id                            └──────┘  └──────┘
src                       └──┘└──────┘└┘└──────┘└┘
typ                       └──┘└──────┘└┘└──────┘└┘
doc                       └──┘        └┘        └┘
txt                       └──┘        └┘        └┘
par                       └──┘        └┘        └┘
pid                         └┘        └┘        
st                       └───────────┘└────────┘
506  | n (succ k) m := by rw [add_succ, add_succ, succ_sub_succ, add_sub_add_right n k m]
id        └──┘                └──────┘  └──────┘  └───────────┘  └───────────────┘   
src       └──┘            └──┘└──────┘└┘└──────┘└┘└───────────┘└┘                    └─
typ       └──┘            └──┘└──────┘└┘└──────┘└┘└───────────┘└┘└───────────────┘└─
doc                       └──┘        └┘        └┘             └┘                    └─
txt                       └──┘        └┘        └┘             └┘                    └─
par                       └──┘        └┘        └┘             └┘                    └─
pid                         └┘        └┘        └┘             └┘                    
st                       └───────────┘└────────┘└─────────────┘└───────────────────────┘
507  
src  
typ  
doc  
txt  
par  
pid  
st   
508  @[ematch_lhs]
src    └────────┘
doc    └────────┘
509  protected theorem add_sub_add_left (k n m : ℕ) : (k + n) - (k + m) = n - m :=
id                                                                 
src                                                                    
typ                                                                
510  by rw [add_comm k n, add_comm k m, nat.add_sub_add_right]
id          └──────┘    └──────┘    └───────────────────┘
src     └──┘└──────┘  └┘└──────┘  └┘└───────────────────┘└─
typ     └──┘└──────┘└┘└──────┘└┘└───────────────────┘└─
doc     └──┘          └┘          └┘                     └─
txt     └──┘          └┘          └┘                     └─
par     └──┘          └┘          └┘                     └─
pid       └┘          └┘          └┘                     
st     └───────────────┘└────────────┘└─────────────────────┘
511  
src  
typ  
doc  
txt  
par  
pid  
st   
512  @[ematch_lhs]
src    └────────┘
doc    └────────┘
513  protected theorem add_sub_cancel (n m : ℕ) : n + m - m = n :=
id                                                     
src                                                      
typ                                                    
514  suffices n + m - (0 + m) = n, from
id                       
src                        
typ                      
515    by rwa [zero_add] at this,
id             └──────┘
src       └───┘└──────┘└───────┘
typ       └───┘└──────┘└───────┘
doc       └───┘        └───────┘
txt       └───┘        └───────┘
par       └───┘        └───────┘
pid          └┘        └──────┘
st       └────────────┘└──────┘
516  by rw [nat.add_sub_add_right, nat.sub_zero]
id          └───────────────────┘  └──────────┘
src     └──┘└───────────────────┘└┘└──────────┘└─
typ     └──┘└───────────────────┘└┘└──────────┘└─
doc     └──┘                     └┘            └─
txt     └──┘                     └┘            └─
par     └──┘                     └┘            └─
pid       └┘                     └┘            
st     └────────────────────────┘└────────────┘
517  
src  
typ  
doc  
txt  
par  
pid  
st   
518  @[ematch_lhs]
src    └────────┘
doc    └────────┘
519  protected theorem add_sub_cancel_left (n m : ℕ) : n + m - n = m :=
id                                                          
src                                                           
typ                                                         
520  show n + m - (n + 0) = m, from
id                   
src                    
typ                  
521  by rw [nat.add_sub_add_left, nat.sub_zero]
id          └──────────────────┘  └──────────┘
src     └──┘└──────────────────┘└┘└──────────┘└─
typ     └──┘└──────────────────┘└┘└──────────┘└─
doc     └──┘                    └┘            └─
txt     └──┘                    └┘            └─
par     └──┘                    └┘            └─
pid       └┘                    └┘            
st     └───────────────────────┘└────────────┘
522  
src  
typ  
doc  
txt  
par  
pid  
st   
523  protected theorem sub_sub : ∀ (n m k : ℕ), n - m - k = n - (m + k)
id                                                       
src                                                          
typ                                                      
524  | n m 0        := by rw [add_zero, nat.sub_zero]
id                            └──────┘  └──────────┘
src                       └──┘└──────┘└┘└──────────┘└┘
typ                       └──┘└──────┘└┘└──────────┘└┘
doc                       └──┘        └┘            └┘
txt                       └──┘        └┘            └┘
par                       └──┘        └┘            └┘
pid                         └┘        └┘            
st                       └───────────┘└────────────┘
525  | n m (succ k) := by rw [add_succ, nat.sub_succ, nat.sub_succ, sub_sub n m k]
id          └──┘              └──────┘  └──────────┘  └──────────┘  └─────┘   
src         └──┘          └──┘└──────┘└┘└──────────┘└┘└──────────┘└┘└─────┘   └─
typ         └──┘          └──┘└──────┘└┘└──────────┘└┘└──────────┘└┘└─────┘└─
doc                       └──┘        └┘            └┘            └┘          └─
txt                       └──┘        └┘            └┘            └┘          └─
par                       └──┘        └┘            └┘            └┘          └─
pid                         └┘        └┘            └┘            └┘          
st                       └───────────┘└────────────┘└────────────┘└─────────────┘
526  
src  
typ  
doc  
txt  
par  
pid  
st   
527  theorem le_of_le_of_sub_le_sub_right {n m k : ℕ}
id                                                 
src                                                
typ                                                
528    (h₀ : k ≤ m)
id             
src            
typ            
529    (h₁ : n - k ≤ m - k)
id                 
src                  
typ                
530  : n ≤ m :=
id       
src      
typ      
531  begin
st   └─────
532    revert k m,
src    └────────┘
typ    └────────┘
doc    └────────┘
txt    └────────┘
par    └────────┘
pid          └──┘
st   ───────────┘└─
533    induction n with n ; intros k m h₀ h₁,
id               
src    └────────┘ └──────┘  └──────────────┘
typ    └────────┘└──────┘  └──────────────┘
doc    └────────┘ └──────┘  └──────────────┘
txt    └────────┘ └──────┘  └──────────────┘
par    └────────┘ └──────┘  └──────────────┘
pid              └────┘        └────────┘
st   ──────────────────────────────────────┘└─
534    { apply zero_le },
id             └─────┘
src      └────┘└─────┘
typ      └────┘└─────┘
doc      └────┘       
txt      └────┘       
par      └────┘       
pid                  
st   ───┘└────────────┘└┘
535    { cases k with k,
id             
src      └────┘ └─────┘
typ      └────┘└─────┘
doc      └────┘ └─────┘
txt      └────┘ └─────┘
par      └────┘ └─────┘
pid            └─────┘
st   ─────────────────┘└─
536      { apply h₁ },
src        └────┘  
typ        └────┘  
doc        └────┘  
txt        └────┘  
par        └────┘  
pid               
st   ─────┘└───────┘└┘
537      cases m with m,
id             
src      └────┘ └─────┘
typ      └────┘└─────┘
doc      └────┘ └─────┘
txt      └────┘ └─────┘
par      └────┘ └─────┘
pid            └─────┘
st   ─────────────────┘└─
538      { cases not_succ_le_zero _ h₀ },
id               └──────────────┘   └┘
src        └────┘└──────────────┘└─┘  
typ        └────┘└──────────────┘└─┘└┘
doc        └────┘                └─┘  
txt        └────┘                └─┘  
par        └────┘                └─┘  
pid                             └─┘  
st   ─────┘└──────────────────────────┘└┘
539      { simp [succ_sub_succ] at h₁,
id               └───────────┘
src        └────┘└───────────┘└─────┘
typ        └────┘└───────────┘└─────┘
doc        └────┘             └─────┘
txt        └────┘             └─────┘
par        └────┘             └─────┘
pid                         └───┘
st   ───────────────────────────────┘└─
540        apply succ_le_succ,
id               └──────────┘
src        └────┘└──────────┘
typ        └────┘└──────────┘
doc        └────┘
txt        └────┘
par        └────┘
pid             
st   ───────────────────────┘└─
541        apply n_ih _ h₁,
id               └──┘   └┘
src        └────┘    └─┘
typ        └────┘└──┘└─┘└┘
doc        └────┘    └─┘
txt        └────┘    └─┘
par        └────┘    └─┘
pid                 └─┘
st   ────────────────────┘└─
542        apply le_of_succ_le_succ h₀ }, }
id               └────────────────┘ └┘
src        └────┘└────────────────┘  
typ        └────┘└────────────────┘└┘
doc        └────┘                    
txt        └────┘                    
par        └────┘                    
pid                                 
st   ─────────────────────────────────┘└────
543  end
st   ──┘
544  
545  protected theorem sub_le_sub_right_iff (n m k : ℕ)
id                                                   
src                                                  
typ                                                  
546    (h : k ≤ m)
id            
src           
typ           
547  : n - k ≤ m - k ↔ n ≤ m :=
id               
src                  
typ              
548  ⟨ le_of_le_of_sub_le_sub_right h , assume h, nat.sub_le_sub_right h k ⟩
id     └──────────────────────────┘             └──────────────────┘  
src    └──────────────────────────┘               └──────────────────┘
typ    └──────────────────────────┘             └──────────────────┘  
549  
550  theorem sub_self_add (n m : ℕ) : n - (n + m) = 0 :=
id                                          
src                                            
typ                                         
551  show (n + 0) - (n + m) = 0, from
id                    
src                      
typ                   
552  by rw [nat.add_sub_add_left, nat.zero_sub]
id          └──────────────────┘  └──────────┘
src     └──┘└──────────────────┘└┘└──────────┘└─
typ     └──┘└──────────────────┘└┘└──────────┘└─
doc     └──┘                    └┘            └─
txt     └──┘                    └┘            └─
par     └──┘                    └┘            └─
pid       └┘                    └┘            
st     └───────────────────────┘└────────────┘
553  
src  
typ  
doc  
txt  
par  
pid  
st   
554  theorem add_le_to_le_sub (x : ℕ) {y k : ℕ}
id                                          
src                                         
typ                                         
555    (h : k ≤ y)
id            
src           
typ           
556  : x + k ≤ y ↔ x ≤ y - k :=
id               
src                  
typ              
557  by rw [← nat.add_sub_cancel x k, nat.sub_le_sub_right_iff _ _ _ h, nat.add_sub_cancel]
id            └────────────────┘    └──────────────────────┘         └────────────────┘
src     └────┘└────────────────┘  └┘└──────────────────────┘└─────┘ └┘└────────────────┘└─
typ     └────┘└────────────────┘└┘└──────────────────────┘└─────┘└┘└────────────────┘└─
doc     └────┘                    └┘                        └─────┘ └┘                  └─
txt     └────┘                    └┘                        └─────┘ └┘                  └─
par     └────┘                    └┘                        └─────┘ └┘                  └─
pid       └──┘                    └┘                        └─────┘ └┘                  
st     └───────────────────────────┘└────────────────────────────────┘└──────────────────┘
558  
src  
typ  
doc  
txt  
par  
pid  
st   
559  lemma sub_lt_of_pos_le (a b : ℕ) (h₀ : 0 < a) (h₁ : a ≤ b)
id                                                      
src                                                      
typ                                                     
560  : b - a < b :=
id         
src         
typ        
561  begin
st   └─────
562    apply sub_lt _ h₀,
id           └────┘   └┘
src    └────┘└────┘└─┘
typ    └────┘└────┘└─┘└┘
doc    └────┘      └─┘
txt    └────┘      └─┘
par    └────┘      └─┘
pid               └─┘
st   ──────────────────┘└─
563    apply lt_of_lt_of_le h₀ h₁
id           └────────────┘ └┘ └┘
src    └────┘└────────────┘    
typ    └────┘└────────────┘└┘└┘
doc    └────┘                  
txt    └────┘                  
par    └────┘                  
pid                           
st   ────────────────────────────┘
564  end
st   └─┘
565  
566  theorem sub_one (n : ℕ) : n - 1 = pred n :=
id                                 └──┘ 
src                                 └──┘
typ                                └──┘ 
567  rfl
id   └─┘
src  └─┘
typ  └─┘
568  
569  theorem succ_sub_one (n : ℕ) : succ n - 1 = n :=
id                                 └──┘      
src                                └──┘      
typ                                └──┘      
570  rfl
id   └─┘
src  └─┘
typ  └─┘
571  
572  theorem succ_pred_eq_of_pos : ∀ {n : ℕ}, n > 0 → succ (pred n) = n
id                                                └──┘  └──┘    
src                                                 └──┘  └──┘    
typ                                               └──┘  └──┘    
573  | 0 h        := absurd h (lt_irrefl 0)
id                  └────┘    └───────┘
src                  └────┘    └───────┘
typ                 └────┘    └───────┘
574  | (succ k) h := rfl
id      └──┘         └─┘
src     └──┘         └─┘
typ     └──┘         └─┘
575  
576  theorem sub_eq_zero_of_le {n m : ℕ} (h : n ≤ m) : n - m = 0 :=
id                                                    
src                                                       
typ                                                   
577  exists.elim (nat.le.dest h)
id   └─────────┘  └─────────┘ 
src  └─────────┘  └─────────┘
typ  └─────────┘  └─────────┘ 
578    (assume k, assume hk : n + k = m, by rw [← hk, sub_self_add])
id                                          └┘  └──────────┘
src                                       └────┘  └┘└──────────┘
typ                                   └────┘└┘└┘└──────────┘
doc                                         └────┘  └┘            
txt                                         └────┘  └┘            
par                                         └────┘  └┘            
pid                                           └──┘  └┘            
st                                         └───────┘└────────────┘
579  
580  protected theorem le_of_sub_eq_zero : ∀{n m : ℕ}, n - m = 0 → n ≤ m
id                                                             
src                                                               
typ                                                            
581  | n 0 H := begin rw [nat.sub_zero] at H, simp [H] end
id                        └──────────┘              
src                   └──┘└──────────┘└────┘  └────┘ └┘
typ                   └──┘└──────────┘└────┘  └────┘└┘
doc                   └──┘            └────┘  └────┘ └┘
txt                   └──┘            └────┘  └────┘ └┘
par                   └──┘            └────┘  └────┘ └┘
pid                     └┘            └───┘       
st              └────────────────────┘└───┘└─────────┘└─┘
582  | 0 (m+1) H := zero_le _
id                 └─────┘
src                └─────┘
typ                └─────┘
583  | (n+1) (m+1) H := add_le_add_right
id                    └──────────────┘
src                   └──────────────┘
typ                   └──────────────┘
584    (le_of_sub_eq_zero begin simp [nat.add_sub_add_right] at H, exact H end) _
id      └───────────────┘             └───────────────────┘              
src                             └────┘└───────────────────┘└────┘  └────┘ 
typ     └───────────────┘       └────┘└───────────────────┘└────┘  └────┘
doc                             └────┘                     └────┘  └────┘ 
txt                             └────┘                     └────┘  └────┘ 
par                             └────┘                     └────┘  └────┘ 
pid                                                      └──┘        
st                        └─────────────────────────────────────┘└────────┘└─┘
585  
586  protected theorem sub_eq_zero_iff_le {n m : ℕ} : n - m = 0 ↔ n ≤ m :=
id                                                            
src                                                             
typ                                                           
587  ⟨nat.le_of_sub_eq_zero, nat.sub_eq_zero_of_le⟩
id    └───────────────────┘  └───────────────────┘
src   └───────────────────┘  └───────────────────┘
typ   └───────────────────┘  └───────────────────┘
588  
589  theorem add_sub_of_le {n m : ℕ} (h : n ≤ m) : n + (m - n) = m :=
id                                                     
src                                                        
typ                                                    
590  exists.elim (nat.le.dest h)
id   └─────────┘  └─────────┘ 
src  └─────────┘  └─────────┘
typ  └─────────┘  └─────────┘ 
591    (assume k, assume hk : n + k = m,
id                               
src                                
typ                              
592      by rw [← hk, nat.add_sub_cancel_left])
id                └┘  └─────────────────────┘
src         └────┘  └┘└─────────────────────┘
typ         └────┘└┘└┘└─────────────────────┘
doc         └────┘  └┘                       
txt         └────┘  └┘                       
par         └────┘  └┘                       
pid           └──┘  └┘                       
st         └───────┘└───────────────────────┘
593  
594  protected theorem sub_add_cancel {n m : ℕ} (h : n ≥ m) : n - m + m = n :=
id                                                              
src                                                                 
typ                                                             
595  by rw [add_comm, add_sub_of_le h]
id          └──────┘  └───────────┘ 
src     └──┘└──────┘└┘└───────────┘ └─
typ     └──┘└──────┘└┘└───────────┘└─
doc     └──┘        └┘              └─
txt     └──┘        └┘              └─
par     └──┘        └┘              └─
pid       └┘        └┘              
st     └───────────┘└───────────────┘
596  
src  
typ  
doc  
txt  
par  
pid  
st   
597  protected theorem add_sub_assoc {m k : ℕ} (h : k ≤ m) (n : ℕ) : n + m - k = n + (m - k) :=
id                                                                         
src                                                                              
typ                                                                        
598  exists.elim (nat.le.dest h)
id   └─────────┘  └─────────┘ 
src  └─────────┘  └─────────┘
typ  └─────────┘  └─────────┘ 
599    (assume l, assume hl : k + l = m,
id                               
src                                
typ                              
600      by rw [← hl, nat.add_sub_cancel_left, add_comm k, ← add_assoc, nat.add_sub_cancel])
id                └┘  └─────────────────────┘  └──────┘     └───────┘  └────────────────┘
src         └────┘  └┘└─────────────────────┘└┘└──────┘ └──┘└───────┘└┘└────────────────┘
typ         └────┘└┘└┘└─────────────────────┘└┘└──────┘└──┘└───────┘└┘└────────────────┘
doc         └────┘  └┘                       └┘         └──┘         └┘                  
txt         └────┘  └┘                       └┘         └──┘         └┘                  
par         └────┘  └┘                       └┘         └──┘         └┘                  
pid           └──┘  └┘                       └┘         └──┘         └┘                  
st         └───────┘└───────────────────────┘└──────────┘└───────────┘└──────────────────┘
601  
602  protected lemma sub_eq_iff_eq_add {a b c : ℕ} (ab : b ≤ a) : a - b = c ↔ a = c + b :=
id                                                                      
src                                                                           
typ                                                                     
603  ⟨assume c_eq, begin rw [c_eq.symm, nat.sub_add_cancel ab] end,
id           └──┘                       └────────────────┘ └┘
src                      └──┘         └┘└────────────────┘  └┘
typ          └──┘        └──┘└───────┘└┘└────────────────┘└┘└┘
doc                      └──┘         └┘                    └┘
txt                      └──┘         └┘                    └┘
par                      └──┘         └┘                    └┘
pid                        └┘         └┘                    
st                 └─────────────────┘└─────────────────────┘└─┘
604    assume a_eq, begin rw [a_eq, nat.add_sub_cancel] end⟩
id            └──┘            └──┘  └────────────────┘
src                       └──┘    └┘└────────────────┘└┘
typ           └──┘        └──┘└──┘└┘└────────────────┘└┘
doc                       └──┘    └┘                  └┘
txt                       └──┘    └┘                  └┘
par                       └──┘    └┘                  └┘
pid                         └┘    └┘                  
st                  └────────────┘└──────────────────┘└─┘
605  
606  protected lemma lt_of_sub_eq_succ {m n l : ℕ} (H : m - n = nat.succ l) : n < m :=
id                                                         └──────┘       
src                                                          └──────┘        
typ                                                        └──────┘       
607  lt_of_not_ge
id   └──────────┘
src  └──────────┘
typ  └──────────┘
608    (assume (H' : n ≥ m), begin simp [nat.sub_eq_zero_of_le H'] at H, contradiction end)
id                                    └───────────────────┘ └┘
src                               └────┘└───────────────────┘  └────┘  └────────────┘
typ                             └────┘└───────────────────┘└┘└────┘  └────────────┘
doc                                └────┘                       └────┘  └────────────┘
txt                                └────┘                       └────┘  └────────────┘
par                                └────┘                       └────┘  └────────────┘
pid                                                           └──┘               
st                           └────────────────────────────────────────┘└──────────────┘└─┘
609  
610  @[simp] lemma zero_min (a : ℕ) : min 0 a = 0 :=
id                                   └─┘    
src                                  └─┘     
typ                                  └─┘    
doc    └──┘
611  min_eq_left (zero_le a)
id   └─────────┘  └─────┘ 
src  └─────────┘  └─────┘
typ  └─────────┘  └─────┘ 
612  
613  @[simp] lemma min_zero (a : ℕ) : min a 0 = 0 :=
id                                   └─┘    
src                                  └─┘     
typ                                  └─┘    
doc    └──┘
614  min_eq_right (zero_le a)
id   └──────────┘  └─────┘ 
src  └──────────┘  └─────┘
typ  └──────────┘  └─────┘ 
615  
616  -- Distribute succ over min
617  theorem min_succ_succ (x y : ℕ) : min (succ x) (succ y) = succ (min x y) :=
id                                    └─┘  └──┘    └──┘    └──┘  └─┘  
src                                   └─┘  └──┘     └──┘     └──┘  └─┘
typ                                   └─┘  └──┘    └──┘    └──┘  └─┘  
618  have f : x ≤ y → min (succ x) (succ y) = succ (min x y), from λp,
id                 └─┘  └──┘    └──┘    └──┘  └─┘           
src                  └─┘  └──┘     └──┘     └──┘  └─┘
typ                └─┘  └──┘    └──┘    └──┘  └─┘           
619    calc min (succ x) (succ y)
id          └─┘  └──┘    └──┘ 
src         └─┘  └──┘     └──┘
typ         └─┘  └──┘    └──┘ 
620                = succ x         : if_pos (succ_le_succ p)
id                   └──┘            └────┘  └──────────┘ 
src                  └──┘             └────┘  └──────────┘
typ                  └──┘            └────┘  └──────────┘ 
621            ... = succ (min x y) : congr_arg succ (eq.symm (if_pos p)),
id                   └──┘  └─┘      └───────┘ └──┘  └─────┘  └────┘ 
src                  └──┘  └─┘        └───────┘ └──┘  └─────┘  └────┘
typ                  └──┘  └─┘      └───────┘ └──┘  └─────┘  └────┘ 
622  have g : ¬ (x ≤ y) → min (succ x) (succ y) = succ (min x y), from λp,
id                    └─┘  └──┘    └──┘    └──┘  └─┘           
src                     └─┘  └──┘     └──┘     └──┘  └─┘
typ                   └─┘  └──┘    └──┘    └──┘  └─┘           
623    calc min (succ x) (succ y)
id          └─┘  └──┘    └──┘ 
src         └─┘  └──┘     └──┘
typ         └─┘  └──┘    └──┘ 
624                = succ y         : if_neg (λeq, p (pred_le_pred eq))
id                   └──┘            └────┘   └┘    └──────────┘ └┘
src                  └──┘             └────┘   └┘     └──────────┘ └┘
typ                  └──┘            └────┘   └┘    └──────────┘ └┘
625            ... = succ (min x y) : congr_arg succ (eq.symm (if_neg p)),
id                   └──┘  └─┘      └───────┘ └──┘  └─────┘  └────┘ 
src                  └──┘  └─┘        └───────┘ └──┘  └─────┘  └────┘
typ                  └──┘  └─┘      └───────┘ └──┘  └─────┘  └────┘ 
626  decidable.by_cases f g
id   └────────────────┘  
src  └────────────────┘
typ  └────────────────┘  
627  
628  theorem sub_eq_sub_min (n m : ℕ) : n - m = n - min n m :=
id                                           └─┘  
src                                             └─┘
typ                                          └─┘  
629  if h : n ≥ m then by rewrite [min_eq_right h]
id   └┘                         └──────────┘ 
src  └┘                  └───────┘└──────────┘ └┘
typ  └┘                └───────┘└──────────┘└┘
doc                       └───────┘             └┘
txt                       └───────┘             └┘
par                       └───────┘             └┘
pid                              └┘             
st                       └──────────────────────┘
630  else by rewrite [sub_eq_zero_of_le (le_of_not_ge h), min_eq_left (le_of_not_ge h), nat.sub_self]
id                    └───────────────┘  └──────────┘    └─────────┘  └──────────┘    └──────────┘
src          └───────┘└───────────────┘ └──────────┘ └─┘└─────────┘ └──────────┘ └─┘└──────────┘└─
typ          └───────┘└───────────────┘ └──────────┘└─┘└─────────┘ └──────────┘└─┘└──────────┘└─
doc          └───────┘                               └─┘                         └─┘            └─
txt          └───────┘                               └─┘                         └─┘            └─
par          └───────┘                               └─┘                         └─┘            └─
pid                 └┘                               └─┘                         └─┘            
st          └──────────────────────────────────────────┘└────────────────────────────┘└────────────┘
631  
src  
typ  
doc  
txt  
par  
pid  
st   
632  @[simp] theorem sub_add_min_cancel (n m : ℕ) : n - m + min n m = n :=
id                                                     └─┘    
src                                                      └─┘     
typ                                                    └─┘    
doc    └──┘
633  by rw [sub_eq_sub_min, nat.sub_add_cancel (min_le_left n m)]
id          └────────────┘  └────────────────┘  └─────────┘  
src     └──┘└────────────┘└┘└────────────────┘ └─────────┘  └──
typ     └──┘└────────────┘└┘└────────────────┘ └─────────┘└──
doc     └──┘              └┘                                └──
txt     └──┘              └┘                                └──
par     └──┘              └┘                                └──
pid       └┘              └┘                                └┘
st     └─────────────────┘└────────────────────────────────────┘
634  
src  
typ  
doc  
txt  
par  
pid  
st   
635  /- TODO(Leo): sub + inequalities -/
src  ────────────────────────────────────
typ  ────────────────────────────────────
doc  ────────────────────────────────────
txt  ────────────────────────────────────
par  ────────────────────────────────────
pid  ────────────────────────────────────
st   ────────────────────────────────────
636  
src  
typ  
doc  
txt  
par  
pid  
st   
637  protected def strong_rec_on {p : nat → Sort u} (n : nat) (h : ∀ n, (∀ m, m < n → p m) → p n) : p n :=
id                                    └─┘                └─┘                                
src                                   └─┘                └─┘                    
typ                                   └─┘                └─┘                                
638  suffices ∀ n m, m < n → p m, from this (succ n) n (lt_succ_self _),
id                              └──┘  └──┘     └──────────┘
src                                         └──┘       └──────────┘
typ                             └──┘  └──┘     └──────────┘
639  begin
st   └─────
640    intros n, induction n with n ih,
id                         
src    └──────┘  └────────┘ └────────┘
typ    └──────┘  └────────┘└────────┘
doc    └──────┘  └────────┘ └────────┘
txt    └──────┘  └────────┘ └────────┘
par    └──────┘  └────────┘ └────────┘
pid          └┘            └───────┘
st   ─────────┘└─────────────────────┘└─
641      {intros m h₁, exact absurd h₁ (not_lt_zero _)},
id                           └────┘ └┘  └─────────┘
src       └─────────┘  └────┘└────┘   └─────────┘└─┘
typ       └─────────┘  └────┘└────┘└┘ └─────────┘└─┘
doc       └─────────┘  └────┘                    └─┘
txt       └─────────┘  └────┘                    └─┘
par       └─────────┘  └────┘                    └─┘
pid             └───┘                           └─┘
st   ───────────────┘└───────────────────────────────┘└┘
642      {intros m h₁,
src       └─────────┘
typ       └─────────┘
doc       └─────────┘
txt       └─────────┘
par       └─────────┘
pid             └───┘
st   ───────────────┘└─
643        apply or.by_cases (lt_or_eq_of_le (le_of_lt_succ h₁)),
id               └─────────┘  └────────────┘  └───────────┘ └┘
src        └────┘└─────────┘ └────────────┘ └───────────┘  └┘
typ        └────┘└─────────┘ └────────────┘ └───────────┘└┘└┘
doc        └────┘                                          └┘
txt        └────┘                                          └┘
par        └────┘                                          └┘
pid                                                       └┘
st   ──────────────────────────────────────────────────────────┘└─
644          {intros, apply ih, assumption},
src           └────┘  └────┘    └────────┘
typ           └────┘  └────┘    └────────┘
doc           └────┘  └────┘    └────────┘
txt           └────┘  └────┘    └────────┘
par           └────┘  └────┘    └────────┘
pid                        
st   ──────────────┘└────────┘└──────────┘└┘
645          {intros, subst m, apply h _ ih}}
id                                     └┘
src           └────┘  └────┘   └────┘ └─┘
typ           └────┘  └────┘  └────┘└─┘└┘
doc           └────┘  └────┘   └────┘ └─┘
txt           └────┘  └────┘   └────┘ └─┘
par           └────┘  └────┘   └────┘ └─┘
pid                                 └─┘
st   ──────────────┘└───────┘└────────────┘└──
646  end
st   ──┘
647  
648  protected lemma strong_induction_on {p : nat → Prop} (n : nat) (h : ∀ n, (∀ m, m < n → p m) → p n) : p n :=
id                                            └─┘              └─┘                                
src                                           └─┘              └─┘                    
typ                                           └─┘              └─┘                                
649  nat.strong_rec_on n h
id   └───────────────┘  
src  └───────────────┘
typ  └───────────────┘  
650  
651  protected lemma case_strong_induction_on {p : nat → Prop} (a : nat)
id                                                 └─┘              └─┘
src                                                └─┘              └─┘
typ                                                └─┘              └─┘
652    (hz : p 0)
id           
typ          
653    (hi : ∀ n, (∀ m, m ≤ n → p m) → p (succ n)) : p a :=
id                                └──┘       
src                                      └──┘
typ                               └──┘       
654  nat.strong_induction_on a $ λ n,
id   └─────────────────────┘      
src  └─────────────────────┘
typ  └─────────────────────┘      
655    match n with
id           
typ          
656    | 0     := λ _, hz
id                    └┘
typ                   └┘
657    | (n+1) := λ h₁, hi n (λ m h₂, h₁ _ (lt_succ_of_le h₂))
id                └┘  └┘       └┘  └┘    └───────────┘ └┘
src                                        └───────────┘
typ               └┘  └┘       └┘  └┘    └───────────┘ └┘
658    end
659  
660  /- mod -/
661  lemma mod_def (x y : nat) : x % y = if 0 < y ∧ y ≤ x then (x - y) % y else x :=
id                        └─┘                                    
src                       └─┘                                    
typ                       └─┘                                    
662  by have h := mod_def_aux x y; rwa [dif_eq_if] at h
id                └─────────┘         └───────┘
src     └────────┘└─────────┘    └───┘└───────┘└──────
typ     └────────┘└─────────┘  └───┘└───────┘└──────
doc     └────────┘               └───┘         └──────
txt     └────────┘               └───┘         └──────
par     └────────┘               └───┘         └──────
pid     └────┘└─┘                  └┘         └───┘
st     └───────────────────────────────┘└───────┘└─────
663  
src  
typ  
doc  
txt  
par  
pid  
st   
664  @[simp] lemma mod_zero (a : nat) : a % 0 = a :=
id                               └─┘         
src                              └─┘         
typ                              └─┘         
doc    └──┘
665  begin
st   └─────
666    rw mod_def,
id        └─────┘
src    └─┘└─────┘
typ    └─┘└─────┘
doc    └─┘
txt    └─┘
par    └─┘
pid      
st   ───────────┘└─
667    have h : ¬ (0 < 0 ∧ 0 ≤ a),
id                          
src    └───────┘ └┘└─┘ └─┘ 
typ    └───────┘ └┘└─┘ └─┘
doc    └───────┘  └┘ └─┘ └─┘  
txt    └───────┘  └┘ └─┘ └─┘  
par    └───────┘  └┘ └─┘ └─┘  
pid    └────┘└─┘  └┘ └─┘ └─┘  
st   ───────────────────────────┘└─
668    simp [lt_irrefl],
id           └───────┘
src    └────┘└───────┘
typ    └────┘└───────┘
doc    └────┘         
txt    └────┘         
par    └────┘         
pid                 
st   ─────────────────┘└─
669    simp [if_neg, h]
id           └────┘  
src    └────┘└────┘└┘ └┘
typ    └────┘└────┘└┘└┘
doc    └────┘      └┘ └┘
txt    └────┘      └┘ └┘
par    └────┘      └┘ └┘
pid              └┘ 
st   ──────────────────┘
670  end
st   └─┘
671  
672  lemma mod_eq_of_lt {a b : nat} (h : a < b) : a % b = a :=
id                             └─┘                 
src                            └─┘                    
typ                            └─┘                 
673  begin
st   └─────
674    rw mod_def,
id        └─────┘
src    └─┘└─────┘
typ    └─┘└─────┘
doc    └─┘
txt    └─┘
par    └─┘
pid      
st   ───────────┘└─
675    have h' : ¬(0 < b ∧ b ≤ a),
id                         
src    └────────┘ └┘    
typ    └────────┘ └┘  
doc    └────────┘  └┘      
txt    └────────┘  └┘      
par    └────────┘  └┘      
pid    └─────┘└─┘  └┘      
st   ───────────────────────────┘└─
676    simp [not_le_of_gt h],
id           └──────────┘ 
src    └────┘└──────────┘ 
typ    └────┘└──────────┘
doc    └────┘             
txt    └────┘             
par    └────┘             
pid                     
st   ──────────────────────┘└─
677    simp [if_neg, h']
id           └────┘  └┘
src    └────┘└────┘└┘  └┘
typ    └────┘└────┘└┘└┘└┘
doc    └────┘      └┘  └┘
txt    └────┘      └┘  └┘
par    └────┘      └┘  └┘
pid              └┘  
st   ───────────────────┘
678  end
st   └─┘
679  
680  @[simp] lemma zero_mod (b : nat) : 0 % b = 0 :=
id                               └─┘        
src                              └─┘         
typ                              └─┘        
doc    └──┘
681  begin
st   └─────
682    rw mod_def,
id        └─────┘
src    └─┘└─────┘
typ    └─┘└─────┘
doc    └─┘
txt    └─┘
par    └─┘
pid      
st   ───────────┘└─
683    have h : ¬(0 < b ∧ b ≤ 0),
id                       
src    └───────┘ └┘   └─┘
typ    └───────┘ └┘  └─┘
doc    └───────┘  └┘     └─┘
txt    └───────┘  └┘     └─┘
par    └───────┘  └┘     └─┘
pid    └────┘└─┘  └┘     └─┘
st   ──────────────────────────┘└─
684    {intro hn, cases hn with l r, exact absurd (lt_of_lt_of_le l r) (lt_irrefl 0)},
id                      └┘                 └────┘  └────────────┘     └───────┘
src     └──────┘  └────┘  └───────┘  └────┘└────┘ └────────────┘  └┘ └───────┘└─┘
typ     └──────┘  └────┘└┘└───────┘  └────┘└────┘ └────────────┘└┘ └───────┘└─┘
doc     └──────┘  └────┘  └───────┘  └────┘                       └┘          └─┘
txt     └──────┘  └────┘  └───────┘  └────┘                       └┘          └─┘
par     └──────┘  └────┘  └───────┘  └────┘                       └┘          └─┘
pid          └─┘         └───────┘                              └┘          └─┘
st   ──────────┘└─────────────────┘└───────────────────────────────────────────────┘└┘
685    simp [if_neg, h]
id           └────┘  
src    └────┘└────┘└┘ └┘
typ    └────┘└────┘└┘└┘
doc    └────┘      └┘ └┘
txt    └────┘      └┘ └┘
par    └────┘      └┘ └┘
pid              └┘ 
st   ──────────────────┘
686  end
st   └─┘
687  
688  lemma mod_eq_sub_mod {a b : nat} (h : a ≥ b) : a % b = (a - b) % b :=
id                               └─┘                       
src                              └─┘                            
typ                              └─┘                       
689  or.elim (eq_zero_or_pos b)
id   └─────┘  └────────────┘ 
src  └─────┘  └────────────┘
typ  └─────┘  └────────────┘ 
690    (λb0, by rw [b0, nat.sub_zero])
id       └┘         └┘  └──────────┘
src             └──┘  └┘└──────────┘
typ      └┘     └──┘└┘└┘└──────────┘
doc             └──┘  └┘            
txt             └──┘  └┘            
par             └──┘  └┘            
pid               └┘  └┘            
st             └─────┘└────────────┘
691    (λh₂, by rw [mod_def, if_pos (and.intro h₂ h)])
id       └┘         └─────┘  └────┘  └───────┘ └┘ 
src             └──┘└─────┘└┘└────┘ └───────┘   └┘
typ      └┘     └──┘└─────┘└┘└────┘ └───────┘└┘└┘
doc             └──┘       └┘                   └┘
txt             └──┘       └┘                   └┘
par             └──┘       └┘                   └┘
pid               └┘       └┘                   └┘
st             └──────────┘└───────────────────────┘
692  
693  lemma mod_lt (x : nat) {y : nat} (h : y > 0) : x % y < y :=
id                     └─┘       └─┘                  
src                    └─┘       └─┘                    
typ                    └─┘       └─┘                  
694  begin
st   └─────
695    induction x using nat.case_strong_induction_on with x ih,
id               
src    └────────┘ └───────────────────────────────────────────┘
typ    └────────┘└───────────────────────────────────────────┘
doc    └────────┘ └───────────────────────────────────────────┘
txt    └────────┘ └───────────────────────────────────────────┘
par    └────────┘ └───────────────────────────────────────────┘
pid              └─────────────────────────────────┘└────────┘
st   ─────────────────────────────────────────────────────────┘└─
696    {rw zero_mod, assumption},
id         └──────┘
src     └─┘└──────┘  └────────┘
typ     └─┘└──────┘  └────────┘
doc     └─┘          └────────┘
txt     └─┘          └────────┘
par     └─┘          └────────┘
pid       
st   ─────┘└──────┘└──────────┘└┘
697    {apply or.elim (decidable.em (succ x < y)),
id            └─────┘  └──────────┘  └──┘   
src     └────┘└─────┘ └──────────┘ └──┘  └┘
typ     └────┘└─────┘ └──────────┘ └──┘└┘
doc     └────┘                            └┘
txt     └────┘                            └┘
par     └────┘                            └┘
pid                                      └┘
st   ───────────────────────────────────────────┘└─
698      {intro h₁, rwa [mod_eq_of_lt h₁]},
id                       └──────────┘ └┘
src       └──────┘  └───┘└──────────┘  
typ       └──────┘  └───┘└──────────┘└┘
doc       └──────┘  └───┘              
txt       └──────┘  └───┘              
par       └──────┘  └───┘              
pid            └─┘     └┘              
st   ────────────┘└────────────────────┘└┘
699      {intro h₁,
src       └──────┘
typ       └──────┘
doc       └──────┘
txt       └──────┘
par       └──────┘
pid            └─┘
st   ────────────┘└─
700        have h₁ : succ x % y = (succ x - y) % y, {exact mod_eq_sub_mod (le_of_not_gt h₁)},
id                               └──┘                 └────────────┘  └──────────┘ └┘
src        └────────┘       └──┘  └┘     └────┘└────────────┘ └──────────┘  
typ        └────────┘       └──┘ └┘    └────┘└────────────┘ └──────────┘└┘
doc        └────────┘                └┘     └────┘                             
txt        └────────┘                └┘     └────┘                             
par        └────────┘                └┘     └────┘                             
pid        └─────┘└─┘                └┘                                       
st   ────────────────────────────────────────────┘└───────────────────────────────────────┘└┘
701        have this : succ x - y ≤ x, {exact le_of_lt_succ (sub_lt (succ_pos x) h)},
id                     └──┘                └───────────┘  └────┘  └──────┘   
src        └──────────┘└──┘       └────┘└───────────┘ └────┘ └──────┘ └┘ 
typ        └──────────┘└──┘     └────┘└───────────┘ └────┘ └──────┘└┘
doc        └──────────┘            └────┘                              └┘ 
txt        └──────────┘            └────┘                              └┘ 
par        └──────────┘            └────┘                              └┘ 
pid        └───────┘└─┘                                               └┘ 
st   ───────────────────────────────┘└────────────────────────────────────────────┘└┘
702        have h₂ : (succ x - y) % y < y, {exact ih _ this},
id                    └──┘                      └┘   └──┘
src        └────────┘ └──┘   └┘       └────┘  └─┘
typ        └────────┘ └──┘  └┘      └────┘└┘└─┘└──┘
doc        └────────┘        └┘       └────┘  └─┘
txt        └────────┘        └┘       └────┘  └─┘
par        └────────┘        └┘       └────┘  └─┘
pid        └─────┘└─┘        └┘              └─┘
st   ───────────────────────────────────┘└────────────────┘└┘
703        rwa [← h₁] at h₂}}
id                └┘
src        └─────┘  └─────┘
typ        └─────┘└┘└─────┘
doc        └─────┘  └─────┘
txt        └─────┘  └─────┘
par        └─────┘  └─────┘
pid           └──┘  └────┘
st   ──────────────┘└────┘└──
704  end
st   ──┘
705  
706  @[simp] theorem mod_self (n : nat) : n % n = 0 :=
id                                 └─┘       
src                                └─┘         
typ                                └─┘       
doc    └──┘
707  by rw [mod_eq_sub_mod (le_refl _), nat.sub_self, zero_mod]
id          └────────────┘  └─────┘     └──────────┘  └──────┘
src     └──┘└────────────┘ └─────┘└───┘└──────────┘└┘└──────┘└─
typ     └──┘└────────────┘ └─────┘└───┘└──────────┘└┘└──────┘└─
doc     └──┘                      └───┘            └┘        └─
txt     └──┘                      └───┘            └┘        └─
par     └──┘                      └───┘            └┘        └─
pid       └┘                      └───┘            └┘        
st     └─────────────────────────────┘└────────────┘└────────┘
708  
src  
typ  
doc  
txt  
par  
pid  
st   
709  @[simp] lemma mod_one (n : ℕ) : n % 1 = 0 :=
id                                      
src                                      
typ                                     
doc    └──┘
710  have n % 1 < 1, from (mod_lt n) (succ_pos 0),
id                      └────┘    └──────┘
src                      └────┘     └──────┘
typ                     └────┘    └──────┘
711  eq_zero_of_le_zero (le_of_lt_succ this)
id   └────────────────┘  └───────────┘ └──┘
src  └────────────────┘  └───────────┘
typ  └────────────────┘  └───────────┘ └──┘
712  
713  lemma mod_two_eq_zero_or_one (n : ℕ) : n % 2 = 0 ∨ n % 2 = 1 :=
id                                                     
src                                                      
typ                                                    
714  match n % 2, @nat.mod_lt n 2 dec_trivial with
id               └────────┘    └─────────┘
src               └────────┘     └─────────┘
typ              └────────┘    └─────────┘
doc                               └─────────┘
715  | 0,   _ := or.inl rfl
id               └────┘ └─┘
src              └────┘ └─┘
typ              └────┘ └─┘
716  | 1,   _ := or.inr rfl
id               └────┘ └─┘
src              └────┘ └─┘
typ              └────┘ └─┘
717  | k+2, h := absurd h dec_trivial
id             └────┘   └─────────┘
src             └────┘   └─────────┘
typ            └────┘   └─────────┘
doc                       └─────────┘
718  end
719  
720  /- div & mod -/
721  lemma div_def (x y : nat) : x / y = if 0 < y ∧ y ≤ x then (x - y) / y + 1 else 0 :=
id                        └─┘                               
src                       └─┘                                       
typ                       └─┘                               
722  by have h := div_def_aux x y; rwa dif_eq_if at h
id                └─────────┘        └───────┘
src     └────────┘└─────────┘    └──┘└───────┘└─────
typ     └────────┘└─────────┘  └──┘└───────┘└─────
doc     └────────┘               └──┘         └─────
txt     └────────┘               └──┘         └─────
par     └────────┘               └──┘         └─────
pid     └────┘└─┘                           └───┘
st     └──────────────────────────────┘└───────┘└─────
723  
src  
typ  
doc  
txt  
par  
pid  
st   
724  lemma mod_add_div (m k : ℕ)
id                            
src                           
typ                           
725  : m % k + k * (m / k) = m :=
id                 
src                    
typ                
726  begin
st   └─────
727    apply nat.strong_induction_on m,
id           └─────────────────────┘ 
src    └────┘└─────────────────────┘
typ    └────┘└─────────────────────┘
doc    └────┘                       
txt    └────┘                       
par    └────┘                       
pid                                
st   ────────────────────────────────┘└─
728    clear m,
src    └─────┘
typ    └─────┘
doc    └─────┘
txt    └─────┘
par    └─────┘
pid         └┘
st   ────────┘└─
729    intros m IH,
src    └─────────┘
typ    └─────────┘
doc    └─────────┘
txt    └─────────┘
par    └─────────┘
pid          └───┘
st   ────────────┘└─
730    cases decidable.em (0 < k ∧ k ≤ m) with h h',
id           └──────────┘          
src    └────┘└──────────┘ └┘   └─────────┘
typ    └────┘└──────────┘ └┘ └─────────┘
doc    └────┘             └┘      └─────────┘
txt    └────┘             └┘      └─────────┘
par    └────┘             └┘      └─────────┘
pid                      └┘      └────────┘
st   ─────────────────────────────────────────────┘└─
731    -- 0 < k ∧ k ≤ m
st   ───────────────────
732    { have h' : m - k < m,
id                       
src      └────────┘   
typ      └────────┘  
doc      └────────┘    
txt      └────────┘    
par      └────────┘    
pid      └─────┘└─┘    
st   ───┘└─────────────────┘└─
733      { apply nat.sub_lt _ h.left,
id               └────────┘   └────┘
src        └────┘└────────┘└─┘└────┘
typ        └────┘└────────┘└─┘└────┘
doc        └────┘          └─┘
txt        └────┘          └─┘
par        └────┘          └─┘
pid                       └─┘
st   ─────┘└───────────────────────┘└─
734        apply lt_of_lt_of_le h.left h.right },
id               └────────────┘ └────┘ └─────┘
src        └────┘└────────────┘└────┘└─────┘
typ        └────┘└────────────┘└────┘└─────┘
doc        └────┘                           
txt        └────┘                           
par        └────┘                           
pid                                        
st   ─────────────────────────────────────────┘└┘
735      rw [div_def, mod_def, if_pos h, if_pos h],
id           └─────┘  └─────┘  └────┘   └────┘ 
src      └──┘└─────┘└┘└─────┘└┘└────┘ └┘└────┘ 
typ      └──┘└─────┘└┘└─────┘└┘└────┘└┘└────┘
doc      └──┘       └┘       └┘       └┘       
txt      └──┘       └┘       └┘       └┘       
par      └──┘       └┘       └┘       └┘       
pid        └┘       └┘       └┘       └┘       
st   ──────────────┘└───────┘└────────┘└────────┘└──
736      simp [left_distrib, IH _ h'],
id             └──────────┘  └┘   └┘
src      └────┘└──────────┘└┘  └─┘  
typ      └────┘└──────────┘└┘└┘└─┘└┘
doc      └────┘            └┘  └─┘  
txt      └────┘            └┘  └─┘  
par      └────┘            └┘  └─┘  
pid                      └┘  └─┘  
st   ───────────────────────────────┘└─
737      rw [← nat.add_sub_assoc h.right, nat.add_sub_cancel_left] },
id             └───────────────┘ └─────┘  └─────────────────────┘
src      └────┘└───────────────┘└─────┘└┘└─────────────────────┘└┘
typ      └────┘└───────────────┘└─────┘└┘└─────────────────────┘└┘
doc      └────┘                        └┘                       └┘
txt      └────┘                        └┘                       └┘
par      └────┘                        └┘                       └┘
pid        └──┘                        └┘                       
st   ──────────────────────────────────┘└───────────────────────┘└┘
738    -- ¬ (0 < k ∧ k ≤ m)
st   ───────────────────────
739    { rw [div_def, mod_def, if_neg h', if_neg h'], simp },
id           └─────┘  └─────┘  └────┘ └┘  └────┘ └┘
src      └──┘└─────┘└┘└─────┘└┘└────┘  └┘└────┘    └───┘
typ      └──┘└─────┘└┘└─────┘└┘└────┘└┘└┘└────┘└┘  └───┘
doc      └──┘       └┘       └┘        └┘          └───┘
txt      └──┘       └┘       └┘        └┘          └───┘
par      └──┘       └┘       └┘        └┘          └───┘
pid        └┘       └┘       └┘        └┘              
st   ──────────────┘└───────┘└─────────┘└─────────┘└─────┘└──
740  end
st   ──┘
741  
742  /- div -/
743  
744  @[simp] protected lemma div_one (n : ℕ) : n / 1 = n :=
id                                                 
src                                                
typ                                                
doc    └──┘
745  have n % 1 + 1 * (n / 1) = n, from mod_add_div _ _,
id                              └─────────┘
src                                └─────────┘
typ                             └─────────┘
746  by simp [mod_one] at this; assumption
id            └─────┘
src     └────┘└─────┘└───────┘  └──────────
typ     └────┘└─────┘└───────┘  └──────────
doc     └────┘       └───────┘  └──────────
txt     └────┘       └───────┘  └──────────
par     └────┘       └───────┘  └──────────
pid                └─────┘            
st     └───────────────────────────────────
747  
src  
typ  
doc  
txt  
par  
pid  
st   
748  @[simp] protected lemma div_zero (n : ℕ) : n / 0 = 0 :=
id                                                 
src                                                 
typ                                                
doc    └──┘
749  begin rw [div_def], simp [lt_irrefl] end
id             └─────┘         └───────┘
src        └──┘└─────┘  └────┘└───────┘└┘
typ        └──┘└─────┘  └────┘└───────┘└┘
doc        └──┘         └────┘         └┘
txt        └──┘         └────┘         └┘
par        └──┘         └────┘         └┘
pid          └┘                      
st   └───────────────┘└──────────────────┘└─┘
750  
751  @[simp] protected lemma zero_div (b : ℕ) : 0 / b = 0 :=
id                                                 
src                                                 
typ                                                
doc    └──┘
752  eq.trans (div_def 0 b) $ if_neg (and.rec not_le_of_gt)
id   └──────┘  └─────┘       └────┘  └─────┘ └──────────┘
src  └──────┘  └─────┘        └────┘  └─────┘ └──────────┘
typ  └──────┘  └─────┘       └────┘  └─────┘ └──────────┘
753  
754  protected lemma div_le_of_le_mul {m n : ℕ} : ∀ {k}, m ≤ k * n → m / k ≤ n
id                                                               
src                                                                   
typ                                                              
755  | 0        h := by simp [nat.div_zero]; apply zero_le
id                            └──────────┘         └─────┘
src                     └────┘└──────────┘  └────┘└─────┘
typ                     └────┘└──────────┘  └────┘└─────┘
doc                     └────┘              └────┘       
txt                     └────┘              └────┘       
par                     └────┘              └────┘       
pid                                                   
st                     └──────────────────────────────────┘
756  | (succ k) h :=
id      └──┘   
src     └──┘
typ     └──┘   
757    suffices succ k * (m / succ k) ≤ succ k * n, from le_of_mul_le_mul_left this (zero_lt_succ _),
id              └──┘       └──┘     └──┘           └───────────────────┘ └──┘  └──────────┘
src             └──┘        └──┘     └──┘            └───────────────────┘       └──────────┘
typ             └──┘       └──┘     └──┘           └───────────────────┘ └──┘  └──────────┘
758    calc
759      succ k * (m / succ k) ≤ m % succ k + succ k * (m / succ k) : le_add_left _ _
id       └──┘       └──┘        └──┘    └──┘       └──┘      └─────────┘
src      └──┘        └──┘         └──┘    └──┘        └──┘      └─────────┘
typ      └──┘       └──┘        └──┘    └──┘       └──┘      └─────────┘
760                        ... = m                                  : by rw mod_add_div
id                                                                         └─────────┘
src                                                                      └─┘└─────────┘
typ                                                                     └─┘└─────────┘
doc                                                                      └─┘           
txt                                                                      └─┘           
par                                                                      └─┘           
pid                                                                                   
st                                                                      └───────────────
761                        ... ≤ succ k * n                         : h
id                               └──┘    
src  ─────────────────────┘      └──┘   
typ  ─────────────────────┘      └──┘    
doc  ─────────────────────┘
txt  ─────────────────────┘
par  ─────────────────────┘
pid  ─────────────────────┘
st   ─────────────────────┘
762  
763  protected lemma div_le_self : ∀ (m n : ℕ), m / n ≤ m
id                                                
src                                                 
typ                                               
764  | m 0        := by simp [nat.div_zero]; apply zero_le
id                            └──────────┘         └─────┘
src                     └────┘└──────────┘  └────┘└─────┘
typ                     └────┘└──────────┘  └────┘└─────┘
doc                     └────┘              └────┘       
txt                     └────┘              └────┘       
par                     └────┘              └────┘       
pid                                                   
st                     └──────────────────────────────────┘
765  | m (succ n) :=
id       └──┘ 
src       └──┘
typ      └──┘ 
766    have m ≤ succ n * m, from calc
id             └──┘   
src            └──┘   
typ            └──┘   
767      m  = 1 * m      : by simp
id              
src                          └────
typ                          └────
doc                           └────
txt                           └────
par                           └────
pid                               
st                           └─────
768     ... ≤ succ n * m : mul_le_mul_right _ (succ_le_succ (zero_le _)),
id            └──┘        └──────────────┘    └──────────┘  └─────┘
src  ──┘      └──┘        └──────────────┘    └──────────┘  └─────┘
typ  ──┘      └──┘        └──────────────┘    └──────────┘  └─────┘
doc  ──┘
txt  ──┘
par  ──┘
pid  ──┘
st   ──┘
769    nat.div_le_of_le_mul this
id     └──────────────────┘ └──┘
src    └──────────────────┘
typ    └──────────────────┘ └──┘
770  
771  lemma div_eq_sub_div {a b : nat} (h₁ : b > 0) (h₂ : a ≥ b) : a / b = (a - b) / b + 1 :=
id                               └─┘                                    
src                              └─┘                                            
typ                              └─┘                                    
772  begin
st   └─────
773    rw [div_def a, if_pos],
id         └─────┘   └────┘
src    └──┘└─────┘ └┘└────┘
typ    └──┘└─────┘└┘└────┘
doc    └──┘        └┘      
txt    └──┘        └┘      
par    └──┘        └┘      
pid      └┘        └┘      
st   ──────────────┘└──────┘└──
774    split ; assumption
src    └────┘  └─────────┘
typ    └────┘  └─────────┘
doc    └────┘  └─────────┘
txt    └────┘  └─────────┘
par    └────┘  └─────────┘
pid                     
st   ────────────────────┘
775  end
st   └─┘
776  
777  lemma div_eq_of_lt {a b : ℕ} (h₀ : a < b) : a / b = 0 :=
id                                              
src                                                 
typ                                             
778  begin
st   └─────
779    rw [div_def a, if_neg],
id         └─────┘   └────┘
src    └──┘└─────┘ └┘└────┘
typ    └──┘└─────┘└┘└────┘
doc    └──┘        └┘      
txt    └──┘        └┘      
par    └──┘        └┘      
pid      └┘        └┘      
st   ──────────────┘└──────┘└──
780    intro h₁,
src    └──────┘
typ    └──────┘
doc    └──────┘
txt    └──────┘
par    └──────┘
pid         └─┘
st   ─────────┘└─
781    apply not_le_of_gt h₀ h₁.right
id           └──────────┘ └┘ └──────┘
src    └────┘└──────────┘  └──────┘
typ    └────┘└──────────┘└┘└──────┘
doc    └────┘                      
txt    └────┘                      
par    └────┘                      
pid                               
st   ────────────────────────────────┘
782  end
st   └─┘
783  
784  -- this is a Galois connection
785  --   f x ≤ y ↔ x ≤ g y
786  -- with
787  --   f x = x * k
788  --   g y = y / k
789  theorem le_div_iff_mul_le (x y : ℕ) {k : ℕ}
id                                           
src                                          
typ                                          
790    (Hk : k > 0)
id            
src            
typ           
791  : x ≤ y / k ↔ x * k ≤ y :=
id               
src                  
typ              
792  begin
st   └─────
793    -- Hk is needed because, despite div being made total, y / 0 := 0
st   ────────────────────────────────────────────────────────────────────
794    --     x * 0 ≤ y ↔ x ≤ y / 0
st   ───────────────────────────────
795    --   ↔ 0 ≤ y ↔ x ≤ 0
st   ───────────────────────
796    --   ↔ true ↔ x = 0
st   ──────────────────────
797    --   ↔ x = 0
st   ───────────────
798    revert x,
src    └──────┘
typ    └──────┘
doc    └──────┘
txt    └──────┘
par    └──────┘
pid          └┘
st   ─────────┘└─
799    apply nat.strong_induction_on y _,
id           └─────────────────────┘ 
src    └────┘└─────────────────────┘ └┘
typ    └────┘└─────────────────────┘└┘
doc    └────┘                        └┘
txt    └────┘                        └┘
par    └────┘                        └┘
pid                                 └┘
st   ──────────────────────────────────┘└─
800    clear y,
src    └─────┘
typ    └─────┘
doc    └─────┘
txt    └─────┘
par    └─────┘
pid         └┘
st   ────────┘└─
801    intros y IH x,
src    └───────────┘
typ    └───────────┘
doc    └───────────┘
txt    └───────────┘
par    └───────────┘
pid          └─────┘
st   ──────────────┘└─
802    cases lt_or_ge y k with h h,
id           └──────┘  
src    └────┘└──────┘  └───────┘
typ    └────┘└──────┘└───────┘
doc    └────┘          └───────┘
txt    └────┘          └───────┘
par    └────┘          └───────┘
pid                   └───────┘
st   ────────────────────────────┘└─
803    -- base case: y < k
st   ──────────────────────
804    { rw [div_eq_of_lt h],
id           └──────────┘ 
src      └──┘└──────────┘ 
typ      └──┘└──────────┘
doc      └──┘             
txt      └──┘             
par      └──┘             
pid        └┘             
st   ───┘└────────────────┘└─
805      cases x with x,
id             
src      └────┘ └─────┘
typ      └────┘└─────┘
doc      └────┘ └─────┘
txt      └────┘ └─────┘
par      └────┘ └─────┘
pid            └─────┘
st   ─────────────────┘└─
806      { simp [zero_mul, zero_le] },
id               └──────┘  └─────┘
src        └────┘└──────┘└┘└─────┘└┘
typ        └────┘└──────┘└┘└─────┘└┘
doc        └────┘        └┘       └┘
txt        └────┘        └┘       └┘
par        └────┘        └┘       └┘
pid                    └┘       
st   ─────┘└───────────────────────┘└┘
807      { simp [succ_mul, not_succ_le_zero],
id               └──────┘  └──────────────┘
src        └────┘└──────┘└┘└──────────────┘
typ        └────┘└──────┘└┘└──────────────┘
doc        └────┘        └┘                
txt        └────┘        └┘                
par        └────┘        └┘                
pid                    └┘                
st   ──────────────────────────────────────┘└─
808        apply not_le_of_gt,
id               └──────────┘
src        └────┘└──────────┘
typ        └────┘└──────────┘
doc        └────┘
txt        └────┘
par        └────┘
pid             
st   ───────────────────────┘└─
809        apply lt_of_lt_of_le h,
id               └────────────┘ 
src        └────┘└────────────┘
typ        └────┘└────────────┘
doc        └────┘              
txt        └────┘              
par        └────┘              
pid                           
st   ───────────────────────────┘└─
810        apply le_add_right } },
id               └──────────┘
src        └────┘└──────────┘
typ        └────┘└──────────┘
doc        └────┘            
txt        └────┘            
par        └────┘            
pid                         
st   ────────────────────────┘└──┘
811    -- step: k ≤ y
st   ─────────────────
812    { rw [div_eq_sub_div Hk h],
id           └────────────┘ └┘ 
src      └──┘└────────────┘   
typ      └──┘└────────────┘└┘
doc      └──┘                 
txt      └──┘                 
par      └──┘                 
pid        └┘                 
st   ──────────────────────────┘└─
813      cases x with x,
id             
src      └────┘ └─────┘
typ      └────┘└─────┘
doc      └────┘ └─────┘
txt      └────┘ └─────┘
par      └────┘ └─────┘
pid            └─────┘
st   ─────────────────┘└─
814      { simp [zero_mul, zero_le] },
id               └──────┘  └─────┘
src        └────┘└──────┘└┘└─────┘└┘
typ        └────┘└──────┘└┘└─────┘└┘
doc        └────┘        └┘       └┘
txt        └────┘        └┘       └┘
par        └────┘        └┘       └┘
pid                    └┘       
st   ─────┘└───────────────────────┘└┘
815      { have Hlt : y - k < y,
id                         
src        └─────────┘  
typ        └─────────┘ 
doc        └─────────┘    
txt        └─────────┘    
par        └─────────┘    
pid        └──────┘└─┘    
st   ─────────────────────────┘└─
816        { apply sub_lt_of_pos_le ; assumption },
id                 └──────────────┘
src          └────┘└──────────────┘  └─────────┘
typ          └────┘└──────────────┘  └─────────┘
doc          └────┘                  └─────────┘
txt          └────┘                  └─────────┘
par          └────┘                  └─────────┘
pid                                           
st   ───────┘└──────────────────────────────────┘└┘
817        rw [ ← add_one
id                └─────┘
src        └─────┘└─────┘
typ        └─────┘└─────┘
doc        └─────┘       
txt        └─────┘       
par        └─────┘       
pid          └───┘       
st   ───────────────────┘
818           , nat.add_le_add_iff_le_right
id              └─────────────────────────┘
src  ──────────┘└─────────────────────────┘
typ  ──────────┘└─────────────────────────┘
doc  ──────────┘                           
txt  ──────────┘                           
par  ──────────┘                           
pid  ──────────┘                           
st   ─────────────────────────────────────┘
819           , IH (y - k) Hlt x
id              └┘       └─┘ 
src  ──────────┘      └┘    
typ  ──────────┘└┘  └┘└─┘
doc  ──────────┘      └┘    
txt  ──────────┘      └┘    
par  ──────────┘      └┘    
pid  ──────────┘      └┘    
st   ──────────────────────────┘
820           , add_one
id              └─────┘
src  ──────────┘└─────┘
typ  ──────────┘└─────┘
doc  ──────────┘       
txt  ──────────┘       
par  ──────────┘       
pid  ──────────┘       
st   ─────────────────┘
821           , succ_mul, add_le_to_le_sub _ h ]
id              └──────┘  └──────────────┘   
src  ──────────┘└──────┘└┘└──────────────┘└─┘ └──
typ  ──────────┘└──────┘└┘└──────────────┘└─┘└──
doc  ──────────┘        └┘                └─┘ └──
txt  ──────────┘        └┘                └─┘ └──
par  ──────────┘        └┘                └─┘ └──
pid  ──────────┘        └┘                └─┘ └┘
st   ──────────────────┘└────────────────────┘└┘
822       } }
src  ────┘
typ  ────┘
doc  ────┘
txt  ────┘
par  ────┘
pid  ────┘
st   ────┘└───
823  end
st   ──┘
824  
825  theorem div_lt_iff_lt_mul (x y : ℕ) {k : ℕ}
id                                           
src                                          
typ                                          
826    (Hk : k > 0)
id            
src            
typ           
827  : x / k < y ↔ x < y * k :=
id               
src                  
typ              
828  begin
st   └─────
829    simp [lt_iff_not_ge],
id           └───────────┘
src    └────┘└───────────┘
typ    └────┘└───────────┘
doc    └────┘             
txt    └────┘             
par    └────┘             
pid                     
st   ─────────────────────┘└─
830    apply not_iff_not_of_iff,
id           └────────────────┘
src    └────┘└────────────────┘
typ    └────┘└────────────────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ─────────────────────────┘└─
831    apply le_div_iff_mul_le _ _ Hk
id           └───────────────┘     └┘
src    └────┘└───────────────┘└───┘  
typ    └────┘└───────────────┘└───┘└┘
doc    └────┘                 └───┘  
txt    └────┘                 └───┘  
par    └────┘                 └───┘  
pid                          └───┘  
st   ────────────────────────────────┘
832  end
st   └─┘
833  
834  def iterate {α : Sort u} (op : α → α) : ℕ → α → α
id                                              
src                                          
typ                                             
835   | 0        a := a
id               
typ              
836   | (succ k) a := iterate k (op a)
id       └──┘       └─────┘    └┘
src      └──┘
typ      └──┘       └─────┘    └┘
837  
838  notation f`^[`n`]` := iterate f n
id                         └─────┘
src                        └─────┘
typ                        └─────┘
839  
840  /- successor and predecessor -/
841  
842  theorem add_one_ne_zero (n : ℕ) : n + 1 ≠ 0 := succ_ne_zero _
id                                              └──────────┘
src                                              └──────────┘
typ                                             └──────────┘
843  
844  theorem eq_zero_or_eq_succ_pred (n : ℕ) : n = 0 ∨ n = succ (pred n) :=
id                                                   └──┘  └──┘ 
src                                                    └──┘  └──┘
typ                                                  └──┘  └──┘ 
845  by cases n; simp
id            
src     └────┘   └────
typ     └────┘  └────
doc     └────┘   └────
txt     └────┘   └────
par     └────┘   └────
pid                 
st     └──────────────
846  
src  
typ  
doc  
txt  
par  
pid  
st   
847  theorem exists_eq_succ_of_ne_zero {n : ℕ} (H : n ≠ 0) : ∃k : ℕ, n = succ k :=
id                                                               └──┘ 
src                                                                └──┘
typ                                                              └──┘ 
848  ⟨_, (eq_zero_or_eq_succ_pred _).resolve_left H⟩
id        └─────────────────────┘   └──────────┘  
src       └─────────────────────┘   └──────────┘
typ       └─────────────────────┘   └──────────┘  
849  
850  theorem succ_inj {n m : ℕ} (H : succ n = succ m) : n = m :=
id                                  └──┘   └──┘       
src                                 └──┘    └──┘        
typ                                 └──┘   └──┘       
851  nat.succ.inj_arrow H id
id   └────────────────┘  └┘
src  └────────────────┘   └┘
typ  └────────────────┘  └┘
852  
853  theorem discriminate {B : Sort u} {n : ℕ} (H1: n = 0 → B) (H2 : ∀m, n = succ m → B) : B :=
id                                                                    └──┘        
src                                                                       └──┘
typ                                                                   └──┘        
854  by induction h : n; [exact H1 h, exact H2 _ h]
id                            └┘         └┘   
src     └────────┘ └─┘   └────┘     └────┘  └─┘
typ     └────────┘ └─┘  └────┘└┘  └────┘└┘└─┘
doc     └────────┘ └─┘    └────┘     └────┘  └─┘
txt     └────────┘ └─┘    └────┘     └────┘  └─┘
par     └────────┘ └─┘    └────┘     └────┘  └─┘
pid               └─┘                     └─┘
st     └──────────────────────────────────────────┘
855  
856  theorem one_succ_zero : 1 = succ 0 := rfl
id                              └──┘      └─┘
src                             └──┘      └─┘
typ                             └──┘      └─┘
857  
858  theorem two_step_induction {P : ℕ → Sort u} (H1 : P 0) (H2 : P 1)
id                                                              
src                                  
typ                                                             
859      (H3 : ∀ (n : ℕ) (IH1 : P n) (IH2 : P (succ n)), P (succ (succ n))) : Π (a : ℕ), P a
id                                         └──┘       └──┘  └──┘                 
src                                           └──┘         └──┘  └──┘               
typ                                        └──┘       └──┘  └──┘                 
860  | 0               := H1
id                        └┘
typ                       └┘
861  | 1               := H2
id                        └┘
typ                       └┘
862  | (succ (succ n)) := H3 _ (two_step_induction _) (two_step_induction _)
id            └──┘        └┘    └────────────────┘     └────────────────┘
src           └──┘
typ           └──┘        └┘    └────────────────┘     └────────────────┘
863  
864  theorem sub_induction {P : ℕ → ℕ → Sort u} (H1 : ∀m, P 0 m)
id                                                        
src                                
typ                                                       
865     (H2 : ∀n, P (succ n) 0) (H3 : ∀n m, P n m → P (succ n) (succ m)) : Π (n m : ℕ), P n m
id                 └──┘                       └──┘    └──┘                   
src                  └──┘                              └──┘     └──┘                
typ                └──┘                       └──┘    └──┘                   
866  | 0        m        := H1 _
id                          └┘
typ                         └┘
867  | (succ n) 0        := H2 _
id      └──┘                └┘
src     └──┘
typ     └──┘                └┘
868  | (succ n) (succ m) := H3 _ _ (sub_induction n m)
id              └──┘      └┘      └───────────┘
src              └──┘
typ             └──┘      └┘      └───────────┘
869  
870  /- addition -/
871  
872  theorem succ_add_eq_succ_add (n m : ℕ) : succ n + m = n + succ m :=
id                                           └──┘       └──┘ 
src                                          └──┘          └──┘
typ                                          └──┘       └──┘ 
873  by simp [succ_add, add_succ]
id            └──────┘  └──────┘
src     └────┘└──────┘└┘└──────┘└─
typ     └────┘└──────┘└┘└──────┘└─
doc     └────┘        └┘        └─
txt     └────┘        └┘        └─
par     └────┘        └┘        └─
pid                 └┘        
st     └──────────────────────────
874  
src  
typ  
doc  
txt  
par  
pid  
st   
875  theorem one_add (n : ℕ) : 1 + n = succ n := by simp
id                                 └──┘ 
src                                 └──┘         └────
typ                                └──┘        └────
doc                                                 └────
txt                                                 └────
par                                                 └────
pid                                                     
st                                                 └─────
876  
src  
typ  
doc  
txt  
par  
pid  
st   
877  protected theorem add_right_comm : ∀ (n m k : ℕ), n + m + k = n + k + m :=
id                                                              
src                                                                 
typ                                                             
878  right_comm nat.add nat.add_comm nat.add_assoc
id   └────────┘ └─────┘ └──────────┘ └───────────┘
src  └────────┘ └─────┘ └──────────┘ └───────────┘
typ  └────────┘ └─────┘ └──────────┘ └───────────┘
879  
880  theorem eq_zero_of_add_eq_zero {n m : ℕ} (H : n + m = 0) : n = 0 ∧ m = 0 :=
id                                                               
src                                                                  
typ                                                              
881  ⟨nat.eq_zero_of_add_eq_zero_right H, nat.eq_zero_of_add_eq_zero_left H⟩
id    └──────────────────────────────┘   └─────────────────────────────┘ 
src   └──────────────────────────────┘    └─────────────────────────────┘
typ   └──────────────────────────────┘   └─────────────────────────────┘ 
882  
883  theorem eq_zero_of_mul_eq_zero : ∀ {n m : ℕ}, n * m = 0 → n = 0 ∨ m = 0
id                                                             
src                                                                 
typ                                                            
884  | 0        m := λ h, or.inl rfl
id                       └────┘ └─┘
src                       └────┘ └─┘
typ                      └────┘ └─┘
885  | (succ n) m :=
id      └──┘
src     └──┘
typ     └──┘
886    begin
st     └─────
887      rw succ_mul, intro h,
id          └──────┘
src      └─┘└──────┘  └─────┘
typ      └─┘└──────┘  └─────┘
doc      └─┘          └─────┘
txt      └─┘          └─────┘
par      └─┘          └─────┘
pid                       └┘
st   ──────────────┘└───────┘└─
888      exact or.inr (eq_zero_of_add_eq_zero_left h)
id             └────┘  └─────────────────────────┘ 
src      └────┘└────┘ └─────────────────────────┘ └─
typ      └────┘└────┘ └─────────────────────────┘└─
doc      └────┘                                   └─
txt      └────┘                                   └─
par      └────┘                                   └─
pid                                              
st   ─────────────────────────────────────────────────
889    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
890  
891  /- properties of inequality -/
892  
893  theorem le_succ_of_pred_le {n m : ℕ} : pred n ≤ m → n ≤ succ m :=
id                                         └──┘        └──┘ 
src                                        └──┘           └──┘
typ                                        └──┘        └──┘ 
894  nat.cases_on n less_than_or_equal.step (λ a, succ_le_succ)
id   └──────────┘  └─────────────────────┘      └──────────┘
src  └──────────┘   └─────────────────────┘       └──────────┘
typ  └──────────┘  └─────────────────────┘      └──────────┘
895  
896  theorem le_lt_antisymm {n m : ℕ} (h₁ : n ≤ m) (h₂ : m < n) : false :=
id                                                         └───┘
src                                                            └───┘
typ                                                        └───┘
897  nat.lt_irrefl n (nat.lt_of_le_of_lt h₁ h₂)
id   └───────────┘   └────────────────┘ └┘ └┘
src  └───────────┘    └────────────────┘
typ  └───────────┘   └────────────────┘ └┘ └┘
898  
899  theorem lt_le_antisymm {n m : ℕ} (h₁ : n < m) (h₂ : m ≤ n) : false :=
id                                                         └───┘
src                                                            └───┘
typ                                                        └───┘
900  le_lt_antisymm h₂ h₁
id   └────────────┘ └┘ └┘
src  └────────────┘
typ  └────────────┘ └┘ └┘
901  
902  protected theorem nat.lt_asymm {n m : ℕ} (h₁ : n < m) : ¬ m < n :=
id                                                          
src                                                           
typ                                                         
903  le_lt_antisymm (nat.le_of_lt h₁)
id   └────────────┘  └──────────┘ └┘
src  └────────────┘  └──────────┘
typ  └────────────┘  └──────────┘ └┘
904  
905  protected def lt_ge_by_cases {a b : ℕ} {C : Sort u} (h₁ : a < b → C) (h₂ : a ≥ b → C) : C :=
id                                                                                  
src                                                                             
typ                                                                                 
906  decidable.by_cases h₁ (λ h, h₂ (or.elim (nat.lt_or_ge a b) (λ a, absurd a h) (λ a, a)))
id   └────────────────┘ └┘      └┘  └─────┘  └──────────┘         └────┘         
src  └────────────────┘              └─────┘  └──────────┘            └────┘
typ  └────────────────┘ └┘      └┘  └─────┘  └──────────┘         └────┘         
907  
908  protected def lt_by_cases {a b : ℕ} {C : Sort u} (h₁ : a < b → C) (h₂ : a = b → C)
id                                                                           
src                                                                          
typ                                                                          
909    (h₃ : b < a → C) : C :=
id                    
src            
typ                   
910  nat.lt_ge_by_cases h₁ (λ h₁,
id   └────────────────┘ └┘    └┘
src  └────────────────┘
typ  └────────────────┘ └┘    └┘
911    nat.lt_ge_by_cases h₃ (λ h, h₂ (nat.le_antisymm h h₁)))
id     └────────────────┘ └┘      └┘  └─────────────┘  └┘
src    └────────────────┘              └─────────────┘
typ    └────────────────┘ └┘      └┘  └─────────────┘  └┘
912  
913  protected theorem lt_trichotomy (a b : ℕ) : a < b ∨ a = b ∨ b < a :=
id                                                        
src                                                           
typ                                                       
914  nat.lt_by_cases (λ h, or.inl h) (λ h, or.inr (or.inl h)) (λ h, or.inr (or.inr h))
id   └─────────────┘      └────┘        └────┘  └────┘         └────┘  └────┘ 
src  └─────────────┘       └────┘          └────┘  └────┘           └────┘  └────┘
typ  └─────────────┘      └────┘        └────┘  └────┘         └────┘  └────┘ 
915  
916  protected theorem eq_or_lt_of_not_lt {a b : ℕ} (hnlt : ¬ a < b) : a = b ∨ b < a :=
id                                                                      
src                                                                         
typ                                                                     
917  (nat.lt_trichotomy a b).resolve_left hnlt
id    └───────────────┘   └──────────┘  └──┘
src   └───────────────┘     └──────────┘
typ   └───────────────┘   └──────────┘  └──┘
918  
919  theorem lt_succ_of_lt {a b : nat} (h : a < b) : a < succ b := le_succ_of_le h
id                                └─┘               └──┘     └───────────┘ 
src                               └─┘                  └──┘      └───────────┘
typ                               └─┘               └──┘     └───────────┘ 
920  
921  def one_pos := nat.zero_lt_one
id                  └─────────────┘
src                 └─────────────┘
typ                 └─────────────┘
922  
923  theorem mul_self_le_mul_self {n m : ℕ} (h : n ≤ m) : n * n ≤ m * m :=
id                                                          
src                                                             
typ                                                         
924  mul_le_mul h h (zero_le _) (zero_le _)
id   └────────┘    └─────┘     └─────┘
src  └────────┘      └─────┘     └─────┘
typ  └────────┘    └─────┘     └─────┘
925  
926  theorem mul_self_lt_mul_self : Π {n m : ℕ}, n < m → n * n < m * m
id                                                        
src                                                           
typ                                                       
927  | 0        m h := mul_pos h h
id                    └─────┘
src                    └─────┘
typ                   └─────┘
928  | (succ n) m h := mul_lt_mul h (le_of_lt h) (succ_pos _) (zero_le _)
id      └──┘          └────────┘    └──────┘     └──────┘     └─────┘
src     └──┘           └────────┘    └──────┘     └──────┘     └─────┘
typ     └──┘          └────────┘    └──────┘     └──────┘     └─────┘
929  
930  theorem mul_self_le_mul_self_iff {n m : ℕ} : n ≤ m ↔ n * n ≤ m * m :=
id                                                         
src                                                            
typ                                                        
931  ⟨mul_self_le_mul_self, λh, decidable.by_contradiction $
id    └──────────────────┘     └────────────────────────┘
src   └──────────────────┘      └────────────────────────┘
typ   └──────────────────┘     └────────────────────────┘
932    λhn, not_lt_of_ge h $ mul_self_lt_mul_self $ lt_of_not_ge hn⟩
id      └┘  └──────────┘    └──────────────────┘   └──────────┘ └┘
src         └──────────┘     └──────────────────┘   └──────────┘
typ     └┘  └──────────┘    └──────────────────┘   └──────────┘ └┘
933  
934  theorem mul_self_lt_mul_self_iff {n m : ℕ} : n < m ↔ n * n < m * m :=
id                                                         
src                                                            
typ                                                        
935  iff.trans (lt_iff_not_ge _ _) $ iff.trans (not_iff_not_of_iff mul_self_le_mul_self_iff) $
id   └───────┘  └───────────┘        └───────┘  └────────────────┘ └──────────────────────┘
src  └───────┘  └───────────┘        └───────┘  └────────────────┘ └──────────────────────┘
typ  └───────┘  └───────────┘        └───────┘  └────────────────┘ └──────────────────────┘
936    iff.symm (lt_iff_not_ge _ _)
id     └──────┘  └───────────┘
src    └──────┘  └───────────┘
typ    └──────┘  └───────────┘
937  
938  theorem le_mul_self : Π (n : ℕ), n ≤ n * n
id                                      
src                                       
typ                                     
939  | 0     := le_refl _
id              └─────┘
src             └─────┘
typ             └─────┘
940  | (n+1) := let t := mul_le_mul_left (n+1) (succ_pos n) in by simp at t; exact t
id                    └─────────────┘       └──────┘                           
src                     └─────────────┘       └──────┘          └───────┘  └────┘ 
typ                   └─────────────┘       └──────┘          └───────┘  └────┘
doc                                                               └───────┘  └────┘ 
txt                                                               └───────┘  └────┘ 
par                                                               └───────┘  └────┘ 
pid                                                                   └──┘        
st                                                               └───────────────────
941  
src  
typ  
doc  
txt  
par  
pid  
st   
942  /- subtraction -/
src  ──────────────────
typ  ──────────────────
doc  ──────────────────
txt  ──────────────────
par  ──────────────────
pid  ──────────────────
st   ──────────────────
943  
src  
typ  
doc  
txt  
par  
pid  
st   
944  protected theorem sub_le_sub_left {n m : ℕ} (k) (h : n ≤ m) : k - m ≤ k - n :=
id                                                                   
src                                                                      
typ                                                                  
945  by induction h; [refl, exact le_trans (pred_le _) h_ih]
id                              └──────┘  └─────┘    └──┘
src     └────────┘   └──┘  └────┘└──────┘ └─────┘└──┘
typ     └────────┘  └──┘  └────┘└──────┘ └─────┘└──┘└──┘
doc     └────────┘    └──┘  └────┘                └──┘
txt     └────────┘    └──┘  └────┘                └──┘
par     └────────┘    └──┘  └────┘                └──┘
pid                                             └──┘
st     └───────────────────────────────────────────────────┘
946  
947  theorem succ_sub_sub_succ (n m k : ℕ) : succ n - m - succ k = n - m - k :=
id                                          └──┘     └──┘       
src                                         └──┘       └──┘         
typ                                         └──┘     └──┘       
948  by rw [nat.sub_sub, nat.sub_sub, add_succ, succ_sub_succ]
id          └─────────┘  └─────────┘  └──────┘  └───────────┘
src     └──┘└─────────┘└┘└─────────┘└┘└──────┘└┘└───────────┘└─
typ     └──┘└─────────┘└┘└─────────┘└┘└──────┘└┘└───────────┘└─
doc     └──┘           └┘           └┘        └┘             └─
txt     └──┘           └┘           └┘        └┘             └─
par     └──┘           └┘           └┘        └┘             └─
pid       └┘           └┘           └┘        └┘             
st     └──────────────┘└───────────┘└────────┘└─────────────┘
949  
src  
typ  
doc  
txt  
par  
pid  
st   
950  protected theorem sub.right_comm (m n k : ℕ) : m - n - k = m - k - n :=
id                                                           
src                                                              
typ                                                          
951  by rw [nat.sub_sub, nat.sub_sub, add_comm]
id          └─────────┘  └─────────┘  └──────┘
src     └──┘└─────────┘└┘└─────────┘└┘└──────┘└─
typ     └──┘└─────────┘└┘└─────────┘└┘└──────┘└─
doc     └──┘           └┘           └┘        └─
txt     └──┘           └┘           └┘        └─
par     └──┘           └┘           └┘        └─
pid       └┘           └┘           └┘        
st     └──────────────┘└───────────┘└────────┘
952  
src  
typ  
doc  
txt  
par  
pid  
st   
953  theorem mul_pred_left : ∀ (n m : ℕ), pred n * m = n * m - m
id                                      └──┘         
src                                      └──┘            
typ                                     └──┘         
954  | 0        m := by simp [nat.zero_sub, pred_zero, zero_mul]
id                            └──────────┘  └───────┘  └──────┘
src                     └────┘└──────────┘└┘└───────┘└┘└──────┘└┘
typ                     └────┘└──────────┘└┘└───────┘└┘└──────┘└┘
doc                     └────┘            └┘         └┘        └┘
txt                     └────┘            └┘         └┘        └┘
par                     └────┘            └┘         └┘        └┘
pid                                     └┘         └┘        
st                     └────────────────────────────────────────┘
955  | (succ n) m := by rw [pred_succ, succ_mul, nat.add_sub_cancel]
id      └──┘                └───────┘  └──────┘  └────────────────┘
src     └──┘            └──┘└───────┘└┘└──────┘└┘└────────────────┘└─
typ     └──┘            └──┘└───────┘└┘└──────┘└┘└────────────────┘└─
doc                     └──┘         └┘        └┘                  └─
txt                     └──┘         └┘        └┘                  └─
par                     └──┘         └┘        └┘                  └─
pid                       └┘         └┘        └┘                  
st                     └────────────┘└────────┘└──────────────────┘
956  
src  
typ  
doc  
txt  
par  
pid  
st   
957  theorem mul_pred_right (n m : ℕ) : n * pred m = n * m - n :=
id                                       └──┘       
src                                       └──┘         
typ                                      └──┘       
958  by rw [mul_comm, mul_pred_left, mul_comm]
id          └──────┘  └───────────┘  └──────┘
src     └──┘└──────┘└┘└───────────┘└┘└──────┘└─
typ     └──┘└──────┘└┘└───────────┘└┘└──────┘└─
doc     └──┘        └┘             └┘        └─
txt     └──┘        └┘             └┘        └─
par     └──┘        └┘             └┘        └─
pid       └┘        └┘             └┘        
st     └───────────┘└─────────────┘└────────┘
959  
src  
typ  
doc  
txt  
par  
pid  
st   
960  protected theorem mul_sub_right_distrib : ∀ (n m k : ℕ), (n - m) * k = n * k - m * k
id                                                                        
src                                                                            
typ                                                                       
961  | n 0        k := by simp [nat.sub_zero]
id                              └──────────┘
src                       └────┘└──────────┘└┘
typ                       └────┘└──────────┘└┘
doc                       └────┘            └┘
txt                       └────┘            └┘
par                       └────┘            └┘
pid                                       
st                       └───────────────────┘
962  | n (succ m) k := by rw [nat.sub_succ, mul_pred_left, mul_sub_right_distrib, succ_mul, nat.sub_sub]
id        └──┘                └──────────┘  └───────────┘  └───────────────────┘  └──────┘  └─────────┘
src       └──┘            └──┘└──────────┘└┘└───────────┘└┘└───────────────────┘└┘└──────┘└┘└─────────┘└─
typ       └──┘            └──┘└──────────┘└┘└───────────┘└┘└───────────────────┘└┘└──────┘└┘└─────────┘└─
doc                       └──┘            └┘             └┘                     └┘        └┘           └─
txt                       └──┘            └┘             └┘                     └┘        └┘           └─
par                       └──┘            └┘             └┘                     └┘        └┘           └─
pid                         └┘            └┘             └┘                     └┘        └┘           
st                       └───────────────┘└─────────────┘└─────────────────────┘└────────┘└───────────┘
963  
src  
typ  
doc  
txt  
par  
pid  
st   
964  protected theorem mul_sub_left_distrib (n m k : ℕ) : n * (m - k) = n * m - n * k :=
id                                                                     
src                                                                         
typ                                                                    
965  by rw [mul_comm, nat.mul_sub_right_distrib, mul_comm m n, mul_comm n k]
id          └──────┘  └───────────────────────┘  └──────┘    └──────┘  
src     └──┘└──────┘└┘└───────────────────────┘└┘└──────┘  └┘└──────┘  └─
typ     └──┘└──────┘└┘└───────────────────────┘└┘└──────┘└┘└──────┘└─
doc     └──┘        └┘                         └┘          └┘          └─
txt     └──┘        └┘                         └┘          └┘          └─
par     └──┘        └┘                         └┘          └┘          └─
pid       └┘        └┘                         └┘          └┘          
st     └───────────┘└─────────────────────────┘└────────────┘└────────────┘
966  
src  
typ  
doc  
txt  
par  
pid  
st   
967  protected theorem mul_self_sub_mul_self_eq (a b : nat) : a * a - b * b = (a + b) * (a - b) :=
id                                                     └─┘                     
src                                                    └─┘                           
typ                                                    └─┘                     
968  by rw [nat.mul_sub_left_distrib, right_distrib, right_distrib, mul_comm b a, add_comm (a*a) (a*b),
id          └──────────────────────┘  └───────────┘  └───────────┘  └──────┘    └──────┘        
src     └──┘└──────────────────────┘└┘└───────────┘└┘└───────────┘└┘└──────┘  └┘└──────┘   └┘    └──
typ     └──┘└──────────────────────┘└┘└───────────┘└┘└───────────┘└┘└──────┘└┘└──────┘   └┘  └──
doc     └──┘                        └┘             └┘             └┘          └┘            └┘    └──
txt     └──┘                        └┘             └┘             └┘          └┘            └┘    └──
par     └──┘                        └┘             └┘             └┘          └┘            └┘    └──
pid       └┘                        └┘             └┘             └┘          └┘            └┘    └──
st     └───────────────────────────┘└─────────────┘└─────────────┘└────────────┘└────────────────────┘└─
969         nat.add_sub_add_left]
id          └──────────────────┘
src  ──────┘└──────────────────┘└─
typ  ──────┘└──────────────────┘└─
doc  ──────┘                    └─
txt  ──────┘                    └─
par  ──────┘                    └─
pid  ──────┘                    
st   ──────────────────────────┘
970  
src  
typ  
doc  
txt  
par  
pid  
st   
971  theorem succ_mul_succ_eq (a b : nat) : succ a * succ b = a*b + a + b + 1 :=
id                                   └─┘    └──┘   └──┘        
src                                  └─┘    └──┘    └──┘             
typ                                  └─┘    └──┘   └──┘        
972  begin rw [← add_one, ← add_one], simp [right_distrib, left_distrib] end
id               └─────┘    └─────┘         └───────────┘  └──────────┘
src        └────┘└─────┘└──┘└─────┘  └────┘└───────────┘└┘└──────────┘└┘
typ        └────┘└─────┘└──┘└─────┘  └────┘└───────────┘└┘└──────────┘└┘
doc        └────┘       └──┘         └────┘             └┘            └┘
txt        └────┘       └──┘         └────┘             └┘            └┘
par        └────┘       └──┘         └────┘             └┘            └┘
pid          └──┘       └──┘                          └┘            
st   └─────────────────┘└─────────┘└────────────────────────────────────┘└─┘
973  
974  theorem succ_sub {m n : ℕ} (h : m ≥ n) : succ m - n = succ (m - n) :=
id                                        └──┘     └──┘    
src                                         └──┘       └──┘    
typ                                       └──┘     └──┘    
975  exists.elim (nat.le.dest h)
id   └─────────┘  └─────────┘ 
src  └─────────┘  └─────────┘
typ  └─────────┘  └─────────┘ 
976    (assume k, assume hk : n + k = m,
id                               
src                                
typ                              
977      by rw [← hk, nat.add_sub_cancel_left, ← add_succ, nat.add_sub_cancel_left])
id                └┘  └─────────────────────┘    └──────┘  └─────────────────────┘
src         └────┘  └┘└─────────────────────┘└──┘└──────┘└┘└─────────────────────┘
typ         └────┘└┘└┘└─────────────────────┘└──┘└──────┘└┘└─────────────────────┘
doc         └────┘  └┘                       └──┘        └┘                       
txt         └────┘  └┘                       └──┘        └┘                       
par         └────┘  └┘                       └──┘        └┘                       
pid           └──┘  └┘                       └──┘        └┘                       
st         └───────┘└───────────────────────┘└──────────┘└───────────────────────┘
978  
979  protected theorem sub_pos_of_lt {m n : ℕ} (h : m < n) : n - m > 0 :=
id                                                          
src                                                             
typ                                                         
980  have 0 + m < n - m + m, begin rw [zero_add, nat.sub_add_cancel (le_of_lt h)], exact h end,
id                             └──────┘  └────────────────┘  └──────┘           
src                            └──┘└──────┘└┘└────────────────┘ └──────┘ └┘  └────┘ 
typ                        └──┘└──────┘└┘└────────────────┘ └──────┘└┘  └────┘
doc                                └──┘        └┘                            └┘  └────┘ 
txt                                └──┘        └┘                            └┘  └────┘ 
par                                └──┘        └┘                            └┘  └────┘ 
pid                                  └┘        └┘                            └┘        
st                           └────────────────┘└───────────────────────────────┘└─────────┘└─┘
981  lt_of_add_lt_add_right this
id   └────────────────────┘ └──┘
src  └────────────────────┘
typ  └────────────────────┘ └──┘
982  
983  protected theorem sub_sub_self {n m : ℕ} (h : m ≤ n) : n - (n - m) = m :=
id                                                              
src                                                                 
typ                                                             
984  (nat.sub_eq_iff_eq_add (nat.sub_le _ _)).2 (eq.symm (add_sub_of_le h))
id    └───────────────────┘  └────────┘         └─────┘  └───────────┘ 
src   └───────────────────┘  └────────┘         └─────┘  └───────────┘
typ   └───────────────────┘  └────────┘         └─────┘  └───────────┘ 
985  
986  protected theorem sub_add_comm {n m k : ℕ} (h : k ≤ n) : n + m - k = n - k + m :=
id                                                                  
src                                                                       
typ                                                                 
987  (nat.sub_eq_iff_eq_add (nat.le_trans h (nat.le_add_right _ _))).2
id    └───────────────────┘  └──────────┘   └──────────────┘       
src   └───────────────────┘  └──────────┘    └──────────────┘       
typ   └───────────────────┘  └──────────┘   └──────────────┘       
988    (by rwa [nat.add_right_comm, nat.sub_add_cancel])
id              └────────────────┘  └────────────────┘
src        └───┘└────────────────┘└┘└────────────────┘
typ        └───┘└────────────────┘└┘└────────────────┘
doc        └───┘                  └┘                  
txt        └───┘                  └┘                  
par        └───┘                  └┘                  
pid           └┘                  └┘                  
st        └──────────────────────┘└──────────────────┘
989  
990  theorem sub_one_sub_lt {n i} (h : i < n) : n - 1 - i < n := begin
id                                                  
src                                                    
typ                                                 
st                                                               └─────
991    rw nat.sub_sub,
id        └─────────┘
src    └─┘└─────────┘
typ    └─┘└─────────┘
doc    └─┘
txt    └─┘
par    └─┘
pid      
st   ───────────────┘└─
992    apply nat.sub_lt,
id           └────────┘
src    └────┘└────────┘
typ    └────┘└────────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ─────────────────┘└─
993    apply lt_of_lt_of_le (nat.zero_lt_succ _) h,
id           └────────────┘  └──────────────┘    
src    └────┘└────────────┘ └──────────────┘└──┘
typ    └────┘└────────────┘ └──────────────┘└──┘
doc    └────┘                               └──┘
txt    └────┘                               └──┘
par    └────┘                               └──┘
pid                                        └──┘
st   ────────────────────────────────────────────┘└─
994    rw add_comm,
id        └──────┘
src    └─┘└──────┘
typ    └─┘└──────┘
doc    └─┘
txt    └─┘
par    └─┘
pid      
st   ────────────┘└─
995    apply nat.zero_lt_succ
id           └──────────────┘
src    └────┘└──────────────┘
typ    └────┘└──────────────┘
doc    └────┘                
txt    └────┘                
par    └────┘                
pid                         
st   ────────────────────────┘
996  end
st   └─┘
997  
998  theorem pred_inj : ∀ {a b : nat}, a > 0 → b > 0 → nat.pred a = nat.pred b → a = b
id                              └─┘               └──────┘   └──────┘      
src                              └─┘                 └──────┘    └──────┘       
typ                             └─┘               └──────┘   └──────┘      
999  | (succ a) (succ b) ha hb h := have a = b, from h, by rw this
id              └──┘                                      └──┘
src              └──┘                                     └─┘    
typ             └──┘                                   └─┘└──┘
doc                                                        └─┘    
txt                                                        └─┘    
par                                                        └─┘    
pid                                                              
st                                                        └───────┘
1000  | (succ a) 0        ha hb h := absurd hb (lt_irrefl _)
id      └──┘                └┘      └────┘     └───────┘
src     └──┘                        └────┘     └───────┘
typ     └──┘                └┘      └────┘     └───────┘
1001  | 0        (succ b) ha hb h := absurd ha (lt_irrefl _)
id               └──┘    └┘         └────┘     └───────┘
src              └──┘               └────┘     └───────┘
typ              └──┘    └┘         └────┘     └───────┘
1002  | 0        0        ha hb h := rfl
id                                  └─┘
src                                 └─┘
typ                                 └─┘
1003  
1004  /- find -/
1005  
1006  section find
1007  parameter {p : ℕ → Prop}
id                  
src                 
typ                 
1008  
1009  private def lbp (m n : ℕ) : Prop := m = n + 1 ∧ ∀ k ≤ n, ¬p k
id                                                     
src                                                      
typ                                                    
1010  
1011  parameters [decidable_pred p] (H : ∃n, p n)
id               └────────────┘            
src              └────────────┘          
typ              └────────────┘            
1012  
1013  private def wf_lbp : well_founded lbp :=
id                        └──────────┘ └─┘
src                       └──────────┘ └─┘
typ                       └──────────┘ └─┘
1014  ⟨let ⟨n, pn⟩ := H in
id    └─┘    └┘     
typ   └─┘    └┘     
1015  suffices ∀m k, n ≤ k + m → acc lbp k, from λa, this _ _ (nat.le_add_left _ _),
id                        └─┘ └─┘           └──┘      └─────────────┘
src                           └─┘ └─┘                       └─────────────┘
typ                       └─┘ └─┘           └──┘      └─────────────┘
1016  λm, nat.rec_on m
id      └────────┘ 
src      └────────┘
typ     └────────┘ 
1017    (λk kn, ⟨_, λy r, match y, r with ._, ⟨rfl, a⟩ := absurd pn (a _ kn) end⟩)
id        └┘                             └─┘       └────┘         └┘
src                                           └─┘        └────┘
typ       └┘                             └─┘       └────┘         └┘
1018    (λm IH k kn, ⟨_, λy r, match y, r with ._, ⟨rfl, a⟩ := IH _ (by rw nat.add_right_comm; exact kn) end⟩)⟩
id        └┘  └┘                             └─┘        └┘          └────────────────┘        └┘
src                                                └─┘                 └─┘└────────────────┘  └────┘
typ       └┘  └┘                             └─┘        └┘       └─┘└────────────────┘  └────┘└┘
doc                                                                    └─┘                    └────┘
txt                                                                    └─┘                    └────┘
par                                                                    └─┘                    └────┘
pid                                                                                               
st                                                                    └──────────────────────────────┘
1019  
1020  protected def find_x : {n // p n ∧ ∀m < n, ¬p m} :=
id                                        
src                                          
typ                                       
1021  @well_founded.fix _ (λk, (∀n < k, ¬p n) → {n // p n ∧ ∀m < n, ¬p m}) lbp wf_lbp
id    └──────────────┘                                    └─┘ └────┘
src   └──────────────┘                                                └─┘ └────┘
typ   └──────────────┘                                    └─┘ └────┘
1022  (λm IH al, if pm : p m then ⟨m, pm, al⟩ else
id      └┘ └┘  └┘                └┘  └┘
src             └┘
typ     └┘ └┘  └┘                └┘  └┘
1023      have ∀ n ≤ m, ¬p n, from λn h, or.elim (lt_or_eq_of_le h) (al n) (λe, by rw e; exact pm),
id       └──┘                    └─────┘  └────────────┘    └┘                     └┘
src                                    └─────┘  └────────────┘                   └─┘   └────┘
typ      └──┘                    └─────┘  └────────────┘    └┘          └─┘  └────┘└┘
doc                                                                               └─┘   └────┘
txt                                                                               └─┘   └────┘
par                                                                               └─┘   └────┘
pid                                                                                         
st                                                                               └─────────────┘
1024      IH _ ⟨rfl, this⟩ (λn h, this n $ nat.le_of_succ_le_succ h))
id       └┘    └─┘  └──┘       └──┘    └────────────────────┘ 
src            └─┘                        └────────────────────┘
typ      └┘    └─┘  └──┘       └──┘    └────────────────────┘ 
1025  0 (λn h, absurd h (nat.not_lt_zero _))
id          └────┘   └─────────────┘
src           └────┘    └─────────────┘
typ         └────┘   └─────────────┘
1026  
1027  protected def find : ℕ := nat.find_x.1
id                            └────────┘
src                           └────────┘
typ                           └────────┘
1028  
1029  protected theorem find_spec : p nat.find := nat.find_x.2.left
id                                  └──────┘    └────────┘ └──┘
src                                  └──────┘    └────────┘ └──┘
typ                                 └──────┘    └────────┘ └──┘
1030  
1031  protected theorem find_min : ∀ {m : ℕ}, m < nat.find → ¬p m := nat.find_x.2.right
id                                            └──────┘        └────────┘ └───┘
src                                            └──────┘          └────────┘ └───┘
typ                                           └──────┘        └────────┘ └───┘
1032  
1033  protected theorem find_min' {m : ℕ} (h : p m) : nat.find ≤ m :=
id                                                └──────┘  
src                                                 └──────┘ 
typ                                               └──────┘  
1034  le_of_not_gt (λ l, find_min l h)
id   └──────────┘      └──────┘  
src  └──────────┘       └──────┘
typ  └──────────┘      └──────┘  
1035  
1036  end find
1037  
1038  /- mod -/
1039  
1040  theorem mod_le (x y : ℕ) : x % y ≤ x :=
id                                 
src                                 
typ                                
1041  or.elim (lt_or_ge x y)
id   └─────┘  └──────┘  
src  └─────┘  └──────┘
typ  └─────┘  └──────┘  
1042    (λxlty, by rw mod_eq_of_lt xlty; refl)
id       └──┘        └──────────┘ └──┘
src               └─┘└──────────┘      └──┘
typ      └──┘     └─┘└──────────┘└──┘  └──┘
doc               └─┘                  └──┘
txt               └─┘                  └──┘
par               └─┘                  └──┘
pid                             
st               └─────────────────────────┘
1043    (λylex, or.elim (eq_zero_or_pos y)
id       └──┘  └─────┘  └────────────┘ 
src            └─────┘  └────────────┘
typ      └──┘  └─────┘  └────────────┘ 
1044      (λy0, by rw [y0, mod_zero]; refl)
id         └┘         └┘  └──────┘
src               └──┘  └┘└──────┘  └──┘
typ        └┘     └──┘└┘└┘└──────┘  └──┘
doc               └──┘  └┘          └──┘
txt               └──┘  └┘          └──┘
par               └──┘  └┘          └──┘
pid                 └┘  └┘        
st               └─────┘└────────┘└────┘
1045      (λypos, le_trans (le_of_lt (mod_lt _ ypos)) ylex))
id         └──┘  └──────┘  └──────┘  └────┘   └──┘   └──┘
src              └──────┘  └──────┘  └────┘
typ        └──┘  └──────┘  └──────┘  └────┘   └──┘   └──┘
1046  
1047  @[simp] theorem add_mod_right (x z : ℕ) : (x + z) % z = x % z :=
id                                                      
src                                                        
typ                                                     
doc    └──┘
1048  by rw [mod_eq_sub_mod (nat.le_add_left _ _), nat.add_sub_cancel]
id          └────────────┘  └─────────────┘       └────────────────┘
src     └──┘└────────────┘ └─────────────┘└─────┘└────────────────┘└─
typ     └──┘└────────────┘ └─────────────┘└─────┘└────────────────┘└─
doc     └──┘                              └─────┘                  └─
txt     └──┘                              └─────┘                  └─
par     └──┘                              └─────┘                  └─
pid       └┘                              └─────┘                  
st     └───────────────────────────────────────┘└──────────────────┘
1049  
src  
typ  
doc  
txt  
par  
pid  
st   
1050  @[simp] theorem add_mod_left (x z : ℕ) : (x + z) % x = z % x :=
id                                                     
src                                                       
typ                                                    
doc    └──┘
1051  by rw [add_comm, add_mod_right]
id          └──────┘  └───────────┘
src     └──┘└──────┘└┘└───────────┘└─
typ     └──┘└──────┘└┘└───────────┘└─
doc     └──┘        └┘             └─
txt     └──┘        └┘             └─
par     └──┘        └┘             └─
pid       └┘        └┘             
st     └───────────┘└─────────────┘
1052  
src  
typ  
doc  
txt  
par  
pid  
st   
1053  @[simp] theorem add_mul_mod_self_left (x y z : ℕ) : (x + y * z) % y = x % y :=
id                                                                  
src                                                                     
typ                                                                 
doc    └──┘
1054  by {induction z with z ih, simp, rw[mul_succ, ← add_assoc, add_mod_right, ih]}
id                                      └──────┘    └───────┘  └───────────┘  └┘
src      └────────┘ └────────┘  └──┘  └─┘└──────┘└──┘└───────┘└┘└───────────┘└┘  
typ      └────────┘└────────┘  └──┘  └─┘└──────┘└──┘└───────┘└┘└───────────┘└┘└┘
doc      └────────┘ └────────┘  └──┘  └─┘        └──┘         └┘             └┘  
txt      └────────┘ └────────┘  └──┘  └─┘        └──┘         └┘             └┘  
par      └────────┘ └────────┘  └──┘  └─┘        └──┘         └┘             └┘  
pid                └───────┘                  └──┘         └┘             └┘  
st     └─────────────────────┘└────┘└───────────┘└───────────┘└─────────────┘└──┘└─┘
1055  
1056  @[simp] theorem add_mul_mod_self_right (x y z : ℕ) : (x + y * z) % z = x % z :=
id                                                                   
src                                                                      
typ                                                                  
doc    └──┘
1057  by rw [mul_comm, add_mul_mod_self_left]
id          └──────┘  └───────────────────┘
src     └──┘└──────┘└┘└───────────────────┘└─
typ     └──┘└──────┘└┘└───────────────────┘└─
doc     └──┘        └┘                     └─
txt     └──┘        └┘                     └─
par     └──┘        └┘                     └─
pid       └┘        └┘                     
st     └───────────┘└─────────────────────┘
1058  
src  
typ  
doc  
txt  
par  
pid  
st   
1059  @[simp] theorem mul_mod_right (m n : ℕ) : (m * n) % m = 0 :=
id                                                   
src                                                     
typ                                                  
doc    └──┘
1060  by rw [← zero_add (m*n), add_mul_mod_self_left, zero_mod]
id            └──────┘     └───────────────────┘  └──────┘
src     └────┘└──────┘   └─┘└───────────────────┘└┘└──────┘└─
typ     └────┘└──────┘ └─┘└───────────────────┘└┘└──────┘└─
doc     └────┘            └─┘                     └┘        └─
txt     └────┘            └─┘                     └┘        └─
par     └────┘            └─┘                     └┘        └─
pid       └──┘            └─┘                     └┘        
st     └───────────────────┘└─────────────────────┘└────────┘
1061  
src  
typ  
doc  
txt  
par  
pid  
st   
1062  @[simp] theorem mul_mod_left (m n : ℕ) : (m * n) % n = 0 :=
id                                                  
src                                                    
typ                                                 
doc    └──┘
1063  by rw [mul_comm, mul_mod_right]
id          └──────┘  └───────────┘
src     └──┘└──────┘└┘└───────────┘└─
typ     └──┘└──────┘└┘└───────────┘└─
doc     └──┘        └┘             └─
txt     └──┘        └┘             └─
par     └──┘        └┘             └─
pid       └┘        └┘             
st     └───────────┘└─────────────┘
1064  
src  
typ  
doc  
txt  
par  
pid  
st   
1065  theorem mul_mod_mul_left (z x y : ℕ) : (z * x) % (z * y) = z * (x % y) :=
id                                                          
src                                                              
typ                                                         
st                                            
1066  if y0 : y = 0 then
id   └┘       
src  └┘        
typ  └┘       
1067    by rw [y0, mul_zero, mod_zero, mod_zero]
id            └┘  └──────┘  └──────┘  └──────┘
src       └──┘  └┘└──────┘└┘└──────┘└┘└──────┘└┘
typ       └──┘└┘└┘└──────┘└┘└──────┘└┘└──────┘└┘
doc       └──┘  └┘        └┘        └┘        └┘
txt       └──┘  └┘        └┘        └┘        └┘
par       └──┘  └┘        └┘        └┘        └┘
pid         └┘  └┘        └┘        └┘        
st       └─────┘└────────┘└────────┘└────────┘
1068  else if z0 : z = 0 then
id        └┘       
src       └┘        
typ       └┘       
1069    by rw [z0, zero_mul, zero_mul, zero_mul, mod_zero]
id            └┘  └──────┘  └──────┘  └──────┘  └──────┘
src       └──┘  └┘└──────┘└┘└──────┘└┘└──────┘└┘└──────┘└┘
typ       └──┘└┘└┘└──────┘└┘└──────┘└┘└──────┘└┘└──────┘└┘
doc       └──┘  └┘        └┘        └┘        └┘        └┘
txt       └──┘  └┘        └┘        └┘        └┘        └┘
par       └──┘  └┘        └┘        └┘        └┘        └┘
pid         └┘  └┘        └┘        └┘        └┘        
st       └─────┘└────────┘└────────┘└────────┘└────────┘
1070  else x.strong_induction_on $ λn IH,
id        └──────────────────┘    └┘
src        └──────────────────┘
typ       └──────────────────┘    └┘
1071    have y0 : y > 0, from nat.pos_of_ne_zero y0,
id                         └────────────────┘ └┘
src                         └────────────────┘
typ                        └────────────────┘ └┘
1072    have z0 : z > 0, from nat.pos_of_ne_zero z0,
id                         └────────────────┘ └┘
src                         └────────────────┘
typ                        └────────────────┘ └┘
1073    or.elim (le_or_gt y n)
id     └─────┘  └──────┘  
src    └─────┘  └──────┘
typ    └─────┘  └──────┘  
1074      (λyn, by rw [
id         └┘
src               └────
typ        └┘     └────
doc               └────
txt               └────
par               └────
pid                 └──
st               └─────
1075          mod_eq_sub_mod yn,
id           └────────────┘ └┘
src  ───────┘└────────────┘  └─
typ  ───────┘└────────────┘└┘└─
doc  ───────┘                └─
txt  ───────┘                └─
par  ───────┘                └─
pid  ───────┘                └─
st   ────────────────────────┘└─
1076          mod_eq_sub_mod (mul_le_mul_left z yn),
id           └────────────┘  └─────────────┘  └┘
src  ───────┘└────────────┘ └─────────────┘   └──
typ  ───────┘└────────────┘ └─────────────┘└┘└──
doc  ───────┘                                 └──
txt  ───────┘                                 └──
par  ───────┘                                 └──
pid  ───────┘                                 └──
st   ────────────────────────────────────────────┘└─
1077          ← nat.mul_sub_left_distrib];
id             └──────────────────────┘
src  ─────────┘└──────────────────────┘
typ  ─────────┘└──────────────────────┘
doc  ─────────┘                        
txt  ─────────┘                        
par  ─────────┘                        
pid  ─────────┘                        
st   ─────────────────────────────────┘└─
1078        exact IH _ (sub_lt (lt_of_lt_of_le y0 yn) y0))
id               └┘    └────┘  └────────────┘    └┘  └┘
src        └────┘  └─┘ └────┘ └────────────┘    └┘  
typ        └────┘└┘└─┘ └────┘ └────────────┘  └┘└┘└┘
doc        └────┘  └─┘                          └┘  
txt        └────┘  └─┘                          └┘  
par        └────┘  └─┘                          └┘  
pid               └─┘                          └┘  
st   ──────────────────────────────────────────────────┘
1079      (λyn, by rw [mod_eq_of_lt yn, mod_eq_of_lt (mul_lt_mul_of_pos_left yn z0)])
id         └┘         └──────────┘ └┘  └──────────┘  └────────────────────┘ └┘ └┘
src               └──┘└──────────┘  └┘└──────────┘ └────────────────────┘    └┘
typ        └┘     └──┘└──────────┘└┘└┘└──────────┘ └────────────────────┘└┘└┘└┘
doc               └──┘              └┘                                       └┘
txt               └──┘              └┘                                       └┘
par               └──┘              └┘                                       └┘
pid                 └┘              └┘                                       └┘
st               └──────────────────┘└───────────────────────────────────────────┘
1080  
1081  theorem mul_mod_mul_right (z x y : ℕ) : (x * z) % (y * z) = (x % y) * z :=
id                                                            
src                                                                
typ                                                           
1082  by rw [mul_comm x z, mul_comm y z, mul_comm (x % y) z]; apply mul_mod_mul_left
id          └──────┘    └──────┘    └──────┘               └──────────────┘
src     └──┘└──────┘  └┘└──────┘  └┘└──────┘   └┘   └────┘└──────────────┘
typ     └──┘└──────┘└┘└──────┘└┘└──────┘ └┘  └────┘└──────────────┘
doc     └──┘          └┘          └┘            └┘   └────┘                
txt     └──┘          └┘          └┘            └┘   └────┘                
par     └──┘          └┘          └┘            └┘   └────┘                
pid       └┘          └┘          └┘            └┘                        
st     └───────────────┘└────────────┘└──────────────────┘└────────────────────────
1083  
src  
typ  
doc  
txt  
par  
pid  
st   
1084  theorem cond_to_bool_mod_two (x : ℕ) [d : decidable (x % 2 = 1)]
id                                            └───────┘      
src                                           └───────┘       
typ                                           └───────┘      
1085  : cond (@to_bool (x % 2 = 1) d) 1 0 = x % 2 :=
id     └──┘   └─────┘                  
src    └──┘   └─────┘                     
typ    └──┘   └─────┘                  
1086  begin
st   └─────
1087    by_cases h : x % 2 = 1,
id                      
src    └───────┘ └─┘ └─┘└┘
typ    └───────┘ └─┘└─┘└┘
doc    └───────┘ └─┘  └─┘ └┘
txt    └───────┘ └─┘  └─┘ └┘
par    └───────┘ └─┘  └─┘ └┘
pid             └─┘  └─┘ 
st   ───────────────────────┘└─
1088    { simp! [*] },
src      └────────┘
typ      └────────┘
doc      └────────┘
txt      └────────┘
par      └────────┘
pid          └─┘
st   ───┘└────────┘└┘
1089    { cases mod_two_eq_zero_or_one x; simp! [*] }
id             └────────────────────┘ 
src      └────┘└────────────────────┘   └────────┘
typ      └────┘└────────────────────┘  └────────┘
doc      └────┘                         └────────┘
txt      └────┘                         └────────┘
par      └────┘                         └────────┘
pid                                        └─┘
st   ─────────────────────────────────────────────┘└─
1090  end
st   ──┘
1091  
1092  theorem sub_mul_mod (x k n : ℕ) (h₁ : n*k ≤ x) : (x - n*k) % n = x % n :=
id                                                        
src                                                              
typ                                                       
1093  begin
st   └─────
1094    induction k with k,
id               
src    └────────┘ └─────┘
typ    └────────┘└─────┘
doc    └────────┘ └─────┘
txt    └────────┘ └─────┘
par    └────────┘ └─────┘
pid              └────┘
st   ───────────────────┘└─
1095    { simp },
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
pid          
st   ───┘└───┘└┘
1096    { have h₂ : n * k ≤ x,
id                     
src      └────────┘  
typ      └────────┘
doc      └────────┘    
txt      └────────┘    
par      └────────┘    
pid      └─────┘└─┘    
st   ──────────────────────┘└─
1097      { rw [mul_succ] at h₁,
id             └──────┘
src        └──┘└──────┘└─────┘
typ        └──┘└──────┘└─────┘
doc        └──┘        └─────┘
txt        └──┘        └─────┘
par        └──┘        └─────┘
pid          └┘        └────┘
st   ─────┘└──────────┘└────┘└─
1098        apply nat.le_trans _ h₁,
id               └──────────┘   └┘
src        └────┘└──────────┘└─┘
typ        └────┘└──────────┘└─┘└┘
doc        └────┘            └─┘
txt        └────┘            └─┘
par        └────┘            └─┘
pid                         └─┘
st   ────────────────────────────┘└─
1099        apply le_add_right _ n },
id               └──────────┘   
src        └────┘└──────────┘└─┘ 
typ        └────┘└──────────┘└─┘
doc        └────┘            └─┘ 
txt        └────┘            └─┘ 
par        └────┘            └─┘ 
pid                         └─┘ 
st   ────────────────────────────┘└┘
1100      have h₄ : x - n * k ≥ n,
id                         
src      └────────┘    
typ      └────────┘  
doc      └────────┘      
txt      └────────┘      
par      └────────┘      
pid      └─────┘└─┘      
st   ──────────────────────────┘└─
1101      { apply @nat.le_of_add_le_add_right (n*k),
id                └────────────────────────┘   
src        └────┘ └────────────────────────┘    
typ        └────┘ └────────────────────────┘  
doc        └────┘                               
txt        └────┘                               
par        └────┘                               
pid                                            
st   ─────┘└─────────────────────────────────────┘└─
1102        rw [nat.sub_add_cancel h₂],
id             └────────────────┘ └┘
src        └──┘└────────────────┘  
typ        └──┘└────────────────┘└┘
doc        └──┘                    
txt        └──┘                    
par        └──┘                    
pid          └┘                    
st   ──────────────────────────────┘└──
1103        simp [mul_succ] at h₁, simp [h₁] },
id               └──────┘               └┘
src        └────┘└──────┘└─────┘  └────┘  └┘
typ        └────┘└──────┘└─────┘  └────┘└┘└┘
doc        └────┘        └─────┘  └────┘  └┘
txt        └────┘        └─────┘  └────┘  └┘
par        └────┘        └─────┘  └────┘  └┘
pid                    └───┘        
st   ──────────────────────────┘└──────────┘└┘
1104      rw [mul_succ, ← nat.sub_sub, ← mod_eq_sub_mod h₄, k_ih h₂] }
id           └──────┘    └─────────┘    └────────────┘ └┘  └──┘ └┘
src      └──┘└──────┘└──┘└─────────┘└──┘└────────────┘  └┘      └┘
typ      └──┘└──────┘└──┘└─────────┘└──┘└────────────┘└┘└┘└──┘└┘└┘
doc      └──┘        └──┘           └──┘                └┘      └┘
txt      └──┘        └──┘           └──┘                └┘      └┘
par      └──┘        └──┘           └──┘                └┘      └┘
pid        └┘        └──┘           └──┘                └┘      
st   ───────────────┘└─────────────┘└───────────────────┘└───────┘└─
1105  end
st   ──┘
1106  
1107  /- div -/
1108  
1109  theorem sub_mul_div (x n p : ℕ) (h₁ : n*p ≤ x) : (x - n*p) / n = x / n - p :=
id                                                          
src                                                                 
typ                                                         
1110  begin
st   └─────
1111    cases eq_zero_or_pos n with h₀ h₀,
id           └────────────┘ 
src    └────┘└────────────┘ └─────────┘
typ    └────┘└────────────┘└─────────┘
doc    └────┘               └─────────┘
txt    └────┘               └─────────┘
par    └────┘               └─────────┘
pid                        └─────────┘
st   ──────────────────────────────────┘└─
1112    { rw [h₀, nat.div_zero, nat.div_zero, nat.zero_sub] },
id           └┘  └──────────┘  └──────────┘  └──────────┘
src      └──┘  └┘└──────────┘└┘└──────────┘└┘└──────────┘└┘
typ      └──┘└┘└┘└──────────┘└┘└──────────┘└┘└──────────┘└┘
doc      └──┘  └┘            └┘            └┘            └┘
txt      └──┘  └┘            └┘            └┘            └┘
par      └──┘  └┘            └┘            └┘            └┘
pid        └┘  └┘            └┘            └┘            
st   ───┘└────┘└────────────┘└────────────┘└────────────┘└┘
1113    { induction p with p,
id                 
src      └────────┘ └─────┘
typ      └────────┘└─────┘
doc      └────────┘ └─────┘
txt      └────────┘ └─────┘
par      └────────┘ └─────┘
pid                └────┘
st   ─────────────────────┘└─
1114      { simp },
src        └───┘
typ        └───┘
doc        └───┘
txt        └───┘
par        └───┘
pid            
st   ─────┘└───┘└┘
1115      { have h₂ : n*p ≤ x,
id                     
src        └────────┘  
typ        └────────┘
doc        └────────┘    
txt        └────────┘    
par        └────────┘    
pid        └─────┘└─┘    
st   ──────────────────────┘└─
1116        { transitivity,
src          └──────────┘
typ          └──────────┘
doc          └──────────┘
txt          └──────────┘
par          └──────────┘
st   ───────┘└──────────┘└─
1117          { apply nat.mul_le_mul_left, apply le_succ },
id                   └─────────────────┘        └─────┘
src            └────┘└─────────────────┘  └────┘└─────┘
typ            └────┘└─────────────────┘  └────┘└─────┘
doc            └────┘                     └────┘       
txt            └────┘                     └────┘       
par            └────┘                     └────┘       
pid                                                  
st   ─────────┘└───────────────────────┘└──────────────┘└┘
1118          { apply h₁ } },
src            └────┘  
typ            └────┘  
doc            └────┘  
txt            └────┘  
par            └────┘  
pid                   
st   ──────────────────┘└──┘
1119        have h₃ : x - n * p ≥ n,
id                           
src        └────────┘    
typ        └────────┘  
doc        └────────┘      
txt        └────────┘      
par        └────────┘      
pid        └─────┘└─┘      
st   ────────────────────────────┘└─
1120        { apply le_of_add_le_add_right,
id                 └────────────────────┘
src          └────┘└────────────────────┘
typ          └────┘└────────────────────┘
doc          └────┘
txt          └────┘
par          └────┘
pid               
st   ───────┘└──────────────────────────┘└─
1121          rw [nat.sub_add_cancel h₂, add_comm],
id               └────────────────┘ └┘  └──────┘
src          └──┘└────────────────┘  └┘└──────┘
typ          └──┘└────────────────┘└┘└┘└──────┘
doc          └──┘                    └┘        
txt          └──┘                    └┘        
par          └──┘                    └┘        
pid            └┘                    └┘        
st   ────────────────────────────────┘└────────┘└──
1122          rw [mul_succ] at h₁,
id               └──────┘
src          └──┘└──────┘└─────┘
typ          └──┘└──────┘└─────┘
doc          └──┘        └─────┘
txt          └──┘        └─────┘
par          └──┘        └─────┘
pid            └┘        └────┘
st   ───────────────────┘└────┘└─
1123          apply h₁ },
src          └────┘  
typ          └────┘  
doc          └────┘  
txt          └────┘  
par          └────┘  
pid                 
st   ────────────────┘└┘
1124        rw [sub_succ, ← p_ih h₂],
id             └──────┘    └──┘ └┘
src        └──┘└──────┘└──┘      
typ        └──┘└──────┘└──┘└──┘└┘
doc        └──┘        └──┘      
txt        └──┘        └──┘      
par        └──┘        └──┘      
pid          └┘        └──┘      
st   ─────────────────┘└─────────┘└──
1125        rw [@div_eq_sub_div (x - n*p) _ h₀ h₃],
id              └────────────┘          └┘ └┘
src        └──┘ └────────────┘      └──┘    
typ        └──┘ └────────────┘   └──┘└┘└┘
doc        └──┘                     └──┘    
txt        └──┘                     └──┘    
par        └──┘                     └──┘    
pid          └┘                     └──┘    
st   ──────────────────────────────────────────┘└──
1126        simp [add_one, pred_succ, mul_succ, nat.sub_sub] } }
id               └─────┘  └───────┘  └──────┘  └─────────┘
src        └────┘└─────┘└┘└───────┘└┘└──────┘└┘└─────────┘└┘
typ        └────┘└─────┘└┘└───────┘└┘└──────┘└┘└─────────┘└┘
doc        └────┘       └┘         └┘        └┘           └┘
txt        └────┘       └┘         └┘        └┘           └┘
par        └────┘       └┘         └┘        └┘           └┘
pid                   └┘         └┘        └┘           
st   ──────────────────────────────────────────────────────┘└───
1127  end
st   ──┘
1128  
1129  theorem div_mul_le_self : ∀ (m n : ℕ), m / n * n ≤ m
id                                              
src                                                
typ                                             
1130  | m 0        := by simp; apply zero_le
id                                  └─────┘
src                     └──┘  └────┘└─────┘
typ                     └──┘  └────┘└─────┘
doc                     └──┘  └────┘       
txt                     └──┘  └────┘       
par                     └──┘  └────┘       
pid                                       
st                     └───────────────────┘
1131  | m (succ n) := (le_div_iff_mul_le _ _ (nat.succ_pos _)).1 (le_refl _)
id        └──┘        └───────────────┘      └──────────┘       └─────┘
src       └──┘        └───────────────┘      └──────────┘       └─────┘
typ       └──┘        └───────────────┘      └──────────┘       └─────┘
1132  
1133  @[simp] theorem add_div_right (x : ℕ) {z : ℕ} (H : z > 0) : (x + z) / z = succ (x / z) :=
id                                                                   └──┘    
src                                                                      └──┘    
typ                                                                  └──┘    
doc    └──┘
1134  by rw [div_eq_sub_div H (nat.le_add_left _ _), nat.add_sub_cancel]
id          └────────────┘   └─────────────┘       └────────────────┘
src     └──┘└────────────┘  └─────────────┘└─────┘└────────────────┘└─
typ     └──┘└────────────┘ └─────────────┘└─────┘└────────────────┘└─
doc     └──┘                               └─────┘                  └─
txt     └──┘                               └─────┘                  └─
par     └──┘                               └─────┘                  └─
pid       └┘                               └─────┘                  
st     └─────────────────────────────────────────┘└──────────────────┘
1135  
src  
typ  
doc  
txt  
par  
pid  
st   
1136  @[simp] theorem add_div_left (x : ℕ) {z : ℕ} (H : z > 0) : (z + x) / z = succ (x / z) :=
id                                                                  └──┘    
src                                                                     └──┘    
typ                                                                 └──┘    
doc    └──┘
1137  by rw [add_comm, add_div_right x H]
id          └──────┘  └───────────┘  
src     └──┘└──────┘└┘└───────────┘  └─
typ     └──┘└──────┘└┘└───────────┘└─
doc     └──┘        └┘               └─
txt     └──┘        └┘               └─
par     └──┘        └┘               └─
pid       └┘        └┘               
st     └───────────┘└─────────────────┘
1138  
src  
typ  
doc  
txt  
par  
pid  
st   
1139  @[simp] theorem mul_div_right (n : ℕ) {m : ℕ} (H : m > 0) : m * n / m = n :=
id                                                                 
src                                                                   
typ                                                                
doc    └──┘
1140  by {induction n; simp [*, mul_succ, -mul_comm]}
id                            └──────┘
src      └────────┘   └───────┘└──────┘└──────────┘
typ      └────────┘  └───────┘└──────┘└──────────┘
doc      └────────┘   └───────┘        └──────────┘
txt      └────────┘   └───────┘        └──────────┘
par      └────────┘   └───────┘        └──────────┘
pid                      └──┘        └──────────┘
st     └──────────────────────────────────────────┘└┘
1141  
1142  @[simp] theorem mul_div_left (m : ℕ) {n : ℕ} (H : n > 0) : m * n / n = m :=
id                                                                
src                                                                  
typ                                                               
doc    └──┘
1143  by rw [mul_comm, mul_div_right _ H]
id          └──────┘  └───────────┘   
src     └──┘└──────┘└┘└───────────┘└─┘ └─
typ     └──┘└──────┘└┘└───────────┘└─┘└─
doc     └──┘        └┘             └─┘ └─
txt     └──┘        └┘             └─┘ └─
par     └──┘        └┘             └─┘ └─
pid       └┘        └┘             └─┘ 
st     └───────────┘└─────────────────┘
1144  
src  
typ  
doc  
txt  
par  
pid  
st   
1145  protected theorem div_self {n : ℕ} (H : n > 0) : n / n = 1 :=
id                                                    
src                                                      
typ                                                   
1146  let t := add_div_right 0 H in by rwa [zero_add, nat.zero_div] at t
id           └───────────┘               └──────┘  └──────────┘
src           └───────────┘           └───┘└──────┘└┘└──────────┘└──────
typ          └───────────┘          └───┘└──────┘└┘└──────────┘└──────
doc                                   └───┘        └┘            └──────
txt                                   └───┘        └┘            └──────
par                                   └───┘        └┘            └──────
pid                                      └┘        └┘            └───┘
st                                   └────────────┘└────────────┘└─────
1147  
src  
typ  
doc  
txt  
par  
pid  
st   
1148  theorem add_mul_div_left (x z : ℕ) {y : ℕ} (H : y > 0) : (x + y * z) / y = x / y + z :=
id                                                                      
src                                                                           
typ                                                                     
1149  by {induction z with z ih, simp, rw [mul_succ, ← add_assoc, add_div_right _ H, ih]}
id                                       └──────┘    └───────┘  └───────────┘     └┘
src      └────────┘ └────────┘  └──┘  └──┘└──────┘└──┘└───────┘└┘└───────────┘└─┘ └┘  
typ      └────────┘└────────┘  └──┘  └──┘└──────┘└──┘└───────┘└┘└───────────┘└─┘└┘└┘
doc      └────────┘ └────────┘  └──┘  └──┘        └──┘         └┘             └─┘ └┘  
txt      └────────┘ └────────┘  └──┘  └──┘        └──┘         └┘             └─┘ └┘  
par      └────────┘ └────────┘  └──┘  └──┘        └──┘         └┘             └─┘ └┘  
pid                └───────┘          └┘        └──┘         └┘             └─┘ └┘  
st     └─────────────────────┘└────┘└────────────┘└───────────┘└─────────────────┘└──┘└─┘
1150  
1151  theorem add_mul_div_right (x y : ℕ) {z : ℕ} (H : z > 0) : (x + y * z) / z = x / z + y :=
id                                                                       
src                                                                            
typ                                                                      
1152  by rw [mul_comm, add_mul_div_left _ _ H]
id          └──────┘  └──────────────┘     
src     └──┘└──────┘└┘└──────────────┘└───┘ └─
typ     └──┘└──────┘└┘└──────────────┘└───┘└─
doc     └──┘        └┘                └───┘ └─
txt     └──┘        └┘                └───┘ └─
par     └──┘        └┘                └───┘ └─
pid       └┘        └┘                └───┘ 
st     └───────────┘└──────────────────────┘
1153  
src  
typ  
doc  
txt  
par  
pid  
st   
1154  protected theorem mul_div_cancel (m : ℕ) {n : ℕ} (H : n > 0) : m * n / n = m :=
id                                                                    
src                                                                      
typ                                                                   
1155  let t := add_mul_div_right 0 m H in by rwa [zero_add, nat.zero_div, zero_add] at t
id           └───────────────┘                └──────┘  └──────────┘  └──────┘
src           └───────────────┘             └───┘└──────┘└┘└──────────┘└┘└──────┘└──────
typ          └───────────────┘           └───┘└──────┘└┘└──────────┘└┘└──────┘└──────
doc                                         └───┘        └┘            └┘        └──────
txt                                         └───┘        └┘            └┘        └──────
par                                         └───┘        └┘            └┘        └──────
pid                                            └┘        └┘            └┘        └───┘
st                                         └────────────┘└────────────┘└────────┘└─────
1156  
src  
typ  
doc  
txt  
par  
pid  
st   
1157  protected theorem mul_div_cancel_left (m : ℕ) {n : ℕ} (H : n > 0) : n * m / n = m :=
id                                                                         
src                                                                           
typ                                                                        
1158  by rw [mul_comm, nat.mul_div_cancel _ H]
id          └──────┘  └────────────────┘   
src     └──┘└──────┘└┘└────────────────┘└─┘ └─
typ     └──┘└──────┘└┘└────────────────┘└─┘└─
doc     └──┘        └┘                  └─┘ └─
txt     └──┘        └┘                  └─┘ └─
par     └──┘        └┘                  └─┘ └─
pid       └┘        └┘                  └─┘ 
st     └───────────┘└──────────────────────┘
1159  
src  
typ  
doc  
txt  
par  
pid  
st   
1160  protected theorem div_eq_of_eq_mul_left {m n k : ℕ} (H1 : n > 0) (H2 : m = k * n) :
id                                                                           
src                                                                            
typ                                                                          
1161    m / n = k :=
id         
src         
typ        
1162  by rw [H2, nat.mul_div_cancel _ H1]
id          └┘  └────────────────┘   └┘
src     └──┘  └┘└────────────────┘└─┘  └─
typ     └──┘└┘└┘└────────────────┘└─┘└┘└─
doc     └──┘  └┘                  └─┘  └─
txt     └──┘  └┘                  └─┘  └─
par     └──┘  └┘                  └─┘  └─
pid       └┘  └┘                  └─┘  
st     └─────┘└───────────────────────┘
1163  
src  
typ  
doc  
txt  
par  
pid  
st   
1164  protected theorem div_eq_of_eq_mul_right {m n k : ℕ} (H1 : n > 0) (H2 : m = n * k) :
id                                                                            
src                                                                             
typ                                                                           
1165    m / n = k :=
id         
src         
typ        
1166  by rw [H2, nat.mul_div_cancel_left _ H1]
id          └┘  └─────────────────────┘   └┘
src     └──┘  └┘└─────────────────────┘└─┘  └─
typ     └──┘└┘└┘└─────────────────────┘└─┘└┘└─
doc     └──┘  └┘                       └─┘  └─
txt     └──┘  └┘                       └─┘  └─
par     └──┘  └┘                       └─┘  └─
pid       └┘  └┘                       └─┘  
st     └─────┘└────────────────────────────┘
1167  
src  
typ  
doc  
txt  
par  
pid  
st   
1168  protected theorem div_eq_of_lt_le {m n k : ℕ}
id                                              
src                                             
typ                                             
1169    (lo : k * n ≤ m) (hi : m < succ k * n) :
id                         └──┘   
src                            └──┘   
typ                        └──┘   
1170    m / n = k :=
id         
src         
typ        
1171  have npos : n > 0, from (eq_zero_or_pos _).resolve_left $ λ hn,
id                          └────────────┘   └──────────┘      └┘
src                          └────────────┘   └──────────┘
typ                         └────────────┘   └──────────┘      └┘
1172    by rw [hn, mul_zero] at hi lo; exact absurd lo (not_le_of_gt hi),
id            └┘  └──────┘                  └────┘ └┘  └──────────┘ └┘
src       └──┘  └┘└──────┘└────────┘  └────┘└────┘   └──────────┘  
typ       └──┘└┘└┘└──────┘└────────┘  └────┘└────┘└┘ └──────────┘└┘
doc       └──┘  └┘        └────────┘  └────┘                       
txt       └──┘  └┘        └────────┘  └────┘                       
par       └──┘  └┘        └────────┘  └────┘                       
pid         └┘  └┘        └───────┘                              
st       └─────┘└────────┘└──────────────────────────────────────────┘
1173  le_antisymm
id   └─────────┘
src  └─────────┘
typ  └─────────┘
1174    (le_of_lt_succ ((nat.div_lt_iff_lt_mul _ _ npos).2 hi))
id      └───────────┘   └───────────────────┘     └──┘   └┘
src     └───────────┘   └───────────────────┘          
typ     └───────────┘   └───────────────────┘     └──┘   └┘
1175    ((nat.le_div_iff_mul_le _ _ npos).2 lo)
id       └───────────────────┘     └──┘   └┘
src      └───────────────────┘          
typ      └───────────────────┘     └──┘   └┘
1176  
1177  theorem mul_sub_div (x n p : ℕ) (h₁ : x < n*p) : (n * p - succ x) / n = p - succ (x / n) :=
id                                                   └──┘        └──┘    
src                                                       └──┘           └──┘    
typ                                                  └──┘        └──┘    
1178  begin
st   └─────
1179    have npos : n > 0 := (eq_zero_or_pos _).resolve_left (λ n0,
id                         └────────────┘
src    └──────────┘ └────┘ └────────────┘└───────────────┘  └────
typ    └──────────┘└────┘ └────────────┘└───────────────┘  └────
doc    └──────────┘  └────┘               └───────────────┘  └────
txt    └──────────┘  └────┘               └───────────────┘  └────
par    └──────────┘  └────┘               └───────────────┘  └────
pid    └───────┘└─┘  └───┘               └───────────────┘  └────
st   ──────────────────────────────────────────────────────────────
1180      by rw [n0, zero_mul] at h₁; exact not_lt_zero _ h₁),
id              └┘  └──────┘               └─────────┘   └┘
src  ───┘  └──┘  └┘└──────┘└─────┘└┘└────┘└─────────┘└─┘  
typ  ───┘  └──┘└┘└┘└──────┘└─────┘└┘└────┘└─────────┘└─┘└┘
doc  ───┘  └──┘  └┘        └─────┘└┘└────┘           └─┘  
txt  ───┘  └──┘  └┘        └─────┘└┘└────┘           └─┘  
par  ───┘  └──┘  └┘        └─────┘└┘└────┘           └─┘  
pid  ───┘  └───┘  └┘        └─────────────┘           └─┘  
st   ─────┘└─────┘└────────┘└────────────────────────────┘└─
1181    apply nat.div_eq_of_lt_le,
id           └─────────────────┘
src    └────┘└─────────────────┘
typ    └────┘└─────────────────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ──────────────────────────┘└─
1182    { rw [nat.mul_sub_right_distrib, mul_comm],
id           └───────────────────────┘  └──────┘
src      └──┘└───────────────────────┘└┘└──────┘
typ      └──┘└───────────────────────┘└┘└──────┘
doc      └──┘                         └┘        
txt      └──┘                         └┘        
par      └──┘                         └┘        
pid        └┘                         └┘        
st   ───┘└───────────────────────────┘└────────┘└──
1183      apply nat.sub_le_sub_left,
id             └─────────────────┘
src      └────┘└─────────────────┘
typ      └────┘└─────────────────┘
doc      └────┘
txt      └────┘
par      └────┘
pid           
st   ────────────────────────────┘└─
1184      exact (div_lt_iff_lt_mul _ _ npos).1 (lt_succ_self _) },
id              └───────────────┘     └──┘     └──────────┘
src      └────┘ └───────────────┘└───┘    └──┘ └──────────┘└──┘
typ      └────┘ └───────────────┘└───┘└──┘└──┘ └──────────┘└──┘
doc      └────┘                  └───┘    └──┘             └──┘
txt      └────┘                  └───┘    └──┘             └──┘
par      └────┘                  └───┘    └──┘             └──┘
pid                             └───┘    └──┘             └─┘
st   ─────────────────────────────────────────────────────────┘└┘
1185    { change succ (pred (n * p - x)) ≤ (succ (pred (p - x / n))) * n,
id                                      └──┘  └──┘              
src      └─────┘             └─┘ └──┘ └──┘     └──┘ 
typ      └─────┘             └─┘ └──┘ └──┘   └──┘ 
doc      └─────┘               └─┘                 └──┘ 
txt      └─────┘               └─┘                 └──┘ 
par      └─────┘               └─┘                 └──┘ 
pid                           └─┘                 └──┘ 
st   ─────────────────────────────────────────────────────────────────┘└─
1186      rw [succ_pred_eq_of_pos (nat.sub_pos_of_lt h₁),
id           └─────────────────┘  └───────────────┘ └┘
src      └──┘└─────────────────┘ └───────────────┘  └──
typ      └──┘└─────────────────┘ └───────────────┘└┘└──
doc      └──┘                                       └──
txt      └──┘                                       └──
par      └──┘                                       └──
pid        └┘                                       └──
st   ─────────────────────────────────────────────────┘└─
1187          succ_pred_eq_of_pos (nat.sub_pos_of_lt _)],
id           └─────────────────┘  └───────────────┘
src  ───────┘└─────────────────┘ └───────────────┘└──┘
typ  ───────┘└─────────────────┘ └───────────────┘└──┘
doc  ───────┘                                     └──┘
txt  ───────┘                                     └──┘
par  ───────┘                                     └──┘
pid  ───────┘                                     └──┘
st   ────────────────────────────────────────────────┘└──
1188      { rw [nat.mul_sub_right_distrib, mul_comm],
id             └───────────────────────┘  └──────┘
src        └──┘└───────────────────────┘└┘└──────┘
typ        └──┘└───────────────────────┘└┘└──────┘
doc        └──┘                         └┘        
txt        └──┘                         └┘        
par        └──┘                         └┘        
pid          └┘                         └┘        
st   ─────┘└───────────────────────────┘└────────┘└──
1189        apply nat.sub_le_sub_left, apply div_mul_le_self },
id               └─────────────────┘        └─────────────┘
src        └────┘└─────────────────┘  └────┘└─────────────┘
typ        └────┘└─────────────────┘  └────┘└─────────────┘
doc        └────┘                     └────┘               
txt        └────┘                     └────┘               
par        └────┘                     └────┘               
pid                                                      
st   ──────────────────────────────┘└──────────────────────┘└┘
1190      { apply (div_lt_iff_lt_mul _ _ npos).2, rwa mul_comm } }
id                └───────────────┘     └──┘         └──────┘
src        └────┘ └───────────────┘└───┘    └─┘  └──┘└──────┘
typ        └────┘ └───────────────┘└───┘└──┘└─┘  └──┘└──────┘
doc        └────┘                  └───┘    └─┘  └──┘        
txt        └────┘                  └───┘    └─┘  └──┘        
par        └────┘                  └───┘    └─┘  └──┘        
pid                               └───┘    └┘             
st   ─────────────────────────────────────────┘└─────────────┘└───
1191  end
st   ──┘
1192  
1193  protected theorem div_div_eq_div_mul (m n k : ℕ) : m / n / k = m / (n * k) :=
id                                                                
src                                                                   
typ                                                               
1194  begin
st   └─────
1195    cases eq_zero_or_pos k with k0 kpos, {rw [k0, mul_zero, nat.div_zero, nat.div_zero]},
id           └────────────┘                     └┘  └──────┘  └──────────┘  └──────────┘
src    └────┘└────────────┘ └───────────┘   └──┘  └┘└──────┘└┘└──────────┘└┘└──────────┘
typ    └────┘└────────────┘└───────────┘   └──┘└┘└┘└──────┘└┘└──────────┘└┘└──────────┘
doc    └────┘               └───────────┘   └──┘  └┘        └┘            └┘            
txt    └────┘               └───────────┘   └──┘  └┘        └┘            └┘            
par    └────┘               └───────────┘   └──┘  └┘        └┘            └┘            
pid                        └───────────┘     └┘  └┘        └┘            └┘            
st   ────────────────────────────────────┘└─────┘└┘└────────┘└────────────┘└────────────┘└─┘
1196    cases eq_zero_or_pos n with n0 npos, {rw [n0, zero_mul, nat.div_zero, nat.zero_div]},
id           └────────────┘                     └┘  └──────┘  └──────────┘  └──────────┘
src    └────┘└────────────┘ └───────────┘   └──┘  └┘└──────┘└┘└──────────┘└┘└──────────┘
typ    └────┘└────────────┘└───────────┘   └──┘└┘└┘└──────┘└┘└──────────┘└┘└──────────┘
doc    └────┘               └───────────┘   └──┘  └┘        └┘            └┘            
txt    └────┘               └───────────┘   └──┘  └┘        └┘            └┘            
par    └────┘               └───────────┘   └──┘  └┘        └┘            └┘            
pid                        └───────────┘     └┘  └┘        └┘            └┘            
st   ────────────────────────────────────┘└─────┘└┘└────────┘└────────────┘└────────────┘└─┘
1197    apply le_antisymm,
id           └─────────┘
src    └────┘└─────────┘
typ    └────┘└─────────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ──────────────────┘└─
1198    { apply (le_div_iff_mul_le _ _ (mul_pos npos kpos)).2,
id              └───────────────┘      └─────┘ └──┘ └──┘
src      └────┘ └───────────────┘└───┘ └─────┘        └──┘
typ      └────┘ └───────────────┘└───┘ └─────┘└──┘└──┘└──┘
doc      └────┘                  └───┘                └──┘
txt      └────┘                  └───┘                └──┘
par      └────┘                  └───┘                └──┘
pid                             └───┘                └┘└┘
st   ───┘└─────────────────────────────────────────────────┘└─
1199      rw [mul_comm n k, ← mul_assoc],
id           └──────┘      └───────┘
src      └──┘└──────┘  └──┘└───────┘
typ      └──┘└──────┘└──┘└───────┘
doc      └──┘          └──┘         
txt      └──┘          └──┘         
par      └──┘          └──┘         
pid        └┘          └──┘         
st   ───────────────────┘└───────────┘└──
1200      apply (le_div_iff_mul_le _ _ npos).1,
id              └───────────────┘     └──┘
src      └────┘ └───────────────┘└───┘    └─┘
typ      └────┘ └───────────────┘└───┘└──┘└─┘
doc      └────┘                  └───┘    └─┘
txt      └────┘                  └───┘    └─┘
par      └────┘                  └───┘    └─┘
pid                             └───┘    └┘
st   ───────────────────────────────────────┘└─
1201      apply (le_div_iff_mul_le _ _ kpos).1,
id              └───────────────┘     └──┘
src      └────┘ └───────────────┘└───┘    └─┘
typ      └────┘ └───────────────┘└───┘└──┘└─┘
doc      └────┘                  └───┘    └─┘
txt      └────┘                  └───┘    └─┘
par      └────┘                  └───┘    └─┘
pid                             └───┘    └┘
st   ───────────────────────────────────────┘└─
1202      refl },
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
pid          
st   ────────┘└┘
1203    { apply (le_div_iff_mul_le _ _ kpos).2,
id              └───────────────┘     └──┘
src      └────┘ └───────────────┘└───┘    └─┘
typ      └────┘ └───────────────┘└───┘└──┘└─┘
doc      └────┘                  └───┘    └─┘
txt      └────┘                  └───┘    └─┘
par      └────┘                  └───┘    └─┘
pid                             └───┘    └┘
st   ───────────────────────────────────────┘└─
1204      apply (le_div_iff_mul_le _ _ npos).2,
id              └───────────────┘     └──┘
src      └────┘ └───────────────┘└───┘    └─┘
typ      └────┘ └───────────────┘└───┘└──┘└─┘
doc      └────┘                  └───┘    └─┘
txt      └────┘                  └───┘    └─┘
par      └────┘                  └───┘    └─┘
pid                             └───┘    └┘
st   ───────────────────────────────────────┘└─
1205      rw [mul_assoc, mul_comm n k],
id           └───────┘  └──────┘  
src      └──┘└───────┘└┘└──────┘  
typ      └──┘└───────┘└┘└──────┘
doc      └──┘         └┘          
txt      └──┘         └┘          
par      └──┘         └┘          
pid        └┘         └┘          
st   ────────────────┘└────────────┘└──
1206      apply (le_div_iff_mul_le _ _ (mul_pos kpos npos)).1,
id              └───────────────┘      └─────┘ └──┘ └──┘
src      └────┘ └───────────────┘└───┘ └─────┘        └──┘
typ      └────┘ └───────────────┘└───┘ └─────┘└──┘└──┘└──┘
doc      └────┘                  └───┘                └──┘
txt      └────┘                  └───┘                └──┘
par      └────┘                  └───┘                └──┘
pid                             └───┘                └┘└┘
st   ──────────────────────────────────────────────────────┘└─
1207      refl }
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
pid          
st   ────────┘└─
1208  end
st   ──┘
1209  
1210  protected theorem mul_div_mul {m : ℕ} (n k : ℕ) (H : m > 0) : m * n / (m * k) = n / k :=
id                                                                         
src                                                                             
typ                                                                        
1211  by rw [← nat.div_div_eq_div_mul, nat.mul_div_cancel_left _ H]
id            └────────────────────┘  └─────────────────────┘   
src     └────┘└────────────────────┘└┘└─────────────────────┘└─┘ └─
typ     └────┘└────────────────────┘└┘└─────────────────────┘└─┘└─
doc     └────┘                      └┘                       └─┘ └─
txt     └────┘                      └┘                       └─┘ └─
par     └────┘                      └┘                       └─┘ └─
pid       └──┘                      └┘                       └─┘ 
st     └───────────────────────────┘└───────────────────────────┘
1212  
src  
typ  
doc  
txt  
par  
pid  
st   
1213  /- dvd -/
src  ──────────
typ  ──────────
doc  ──────────
txt  ──────────
par  ──────────
pid  ──────────
st   ──────────
1214  
src  
typ  
doc  
txt  
par  
pid  
st   
1215  protected theorem dvd_add_iff_right {k m n : ℕ} (h : k ∣ m) : k ∣ n ↔ k ∣ m + n :=
id                                                                     
src                                                                         
typ                                                                    
1216  ⟨dvd_add h, dvd.elim h $ λd hd, match m, hd with
id    └─────┘   └──────┘      └┘          └┘
src   └─────┘    └──────┘
typ   └─────┘   └──────┘      └┘          └┘
1217  | ._, rfl := λh₂, dvd.elim h₂ $ λe he, ⟨e - d,
id         └─┘     └┘  └──────┘ └┘     └┘     
src        └─┘         └──────┘                
typ        └─┘     └┘  └──────┘ └┘     └┘     
1218    by rw [nat.mul_sub_left_distrib, ← he, nat.add_sub_cancel_left]⟩
id            └──────────────────────┘    └┘  └─────────────────────┘
src       └──┘└──────────────────────┘└──┘  └┘└─────────────────────┘
typ       └──┘└──────────────────────┘└──┘└┘└┘└─────────────────────┘
doc       └──┘                        └──┘  └┘                       
txt       └──┘                        └──┘  └┘                       
par       └──┘                        └──┘  └┘                       
pid         └┘                        └──┘  └┘                       
st       └───────────────────────────┘└────┘└───────────────────────┘
1219  end⟩
1220  
1221  protected theorem dvd_add_iff_left {k m n : ℕ} (h : k ∣ n) : k ∣ m ↔ k ∣ m + n :=
id                                                                    
src                                                                        
typ                                                                   
1222  by rw add_comm; exact nat.dvd_add_iff_right h
id         └──────┘        └───────────────────┘ 
src     └─┘└──────┘  └────┘└───────────────────┘ 
typ     └─┘└──────┘  └────┘└───────────────────┘
doc     └─┘          └────┘                      
txt     └─┘          └────┘                      
par     └─┘          └────┘                      
pid                                            
st     └───────────────────────────────────────────
1223  
src  
typ  
doc  
txt  
par  
pid  
st   
1224  theorem dvd_sub {k m n : ℕ} (H : n ≤ m) (h₁ : k ∣ m) (h₂ : k ∣ n) : k ∣ m - n :=
id                                                                 
src                                                                       
typ                                                                
1225  (nat.dvd_add_iff_left h₂).2 $ by rw nat.sub_add_cancel H; exact h₁
id    └──────────────────┘ └┘           └────────────────┘         └┘
src   └──────────────────┘           └─┘└────────────────┘   └────┘  
typ   └──────────────────┘ └┘        └─┘└────────────────┘  └────┘└┘
doc                                   └─┘                     └────┘  
txt                                   └─┘                     └────┘  
par                                   └─┘                     └────┘  
pid                                                                 
st                                   └──────────────────────────────────
1226  
src  
typ  
doc  
txt  
par  
pid  
st   
1227  theorem dvd_mod_iff {k m n : ℕ} (h : k ∣ n) : k ∣ m % n ↔ k ∣ m :=
id                                                     
src                                                         
typ                                                    
1228  let t := @nat.dvd_add_iff_left _ (m % n) _ (dvd_trans h (dvd_mul_right n (m / n))) in
id            └──────────────────┘           └───────┘   └───────────┘     
src            └──────────────────┘             └───────┘    └───────────┘      
typ           └──────────────────┘           └───────┘   └───────────┘     
1229  by rwa mod_add_div at t
id          └─────────┘
src     └──┘└─────────┘└─────
typ     └──┘└─────────┘└─────
doc     └──┘           └─────
txt     └──┘           └─────
par     └──┘           └─────
pid                   └───┘
st     └─────────────────────
1230  
src  
typ  
doc  
txt  
par  
pid  
st   
1231  theorem le_of_dvd {m n : ℕ} (h : n > 0) : m ∣ n → m ≤ n :=
id                                                 
src                                                   
typ                                                
1232  λ⟨k, e⟩, by {
id    
typ   
st              └──
1233    revert h, rw e, refine k.cases_on _ _,
id                           └────────┘
src    └──────┘  └─┘   └─────┘└────────┘└──┘
typ    └──────┘  └─┘  └─────┘└────────┘└──┘
doc    └──────┘  └─┘   └─────┘          └──┘
txt    └──────┘  └─┘   └─────┘          └──┘
par    └──────┘  └─┘   └─────┘          └──┘
pid          └┘                       └──┘
st   ─────────┘└────┘└─────────────────────┘└─
1234    exact λhn, absurd hn (lt_irrefl _),
id                └────┘     └───────┘
src    └────┘ └──┘└────┘   └───────┘└─┘
typ    └────┘ └──┘└────┘   └───────┘└─┘
doc    └────┘ └──┘                  └─┘
txt    └────┘ └──┘                  └─┘
par    └────┘ └──┘                  └─┘
pid          └──┘                  └─┘
st   ───────────────────────────────────┘└─
1235    exact λk _, let t := mul_le_mul_left m (succ_pos k) in by rwa mul_one at t }
id                          └─────────────┘   └──────┘              └─────┘
src    └────┘ └───┘   └────┘└─────────────┘  └──────┘ └───┘  └──┘└─────┘└────┘
typ    └────┘ └───┘   └────┘└─────────────┘ └──────┘ └───┘  └──┘└─────┘└────┘
doc    └────┘ └───┘   └────┘                          └───┘  └──┘       └────┘
txt    └────┘ └───┘   └────┘                          └───┘  └──┘       └────┘
par    └────┘ └───┘   └────┘                          └───┘  └──┘       └────┘
pid          └───┘   └────┘                          └───┘  └───┘       └────┘
st   ──────────────────────────────────────────────────────────┘└────────────────┘└┘
1236  
1237  theorem dvd_antisymm : Π {m n : ℕ}, m ∣ n → n ∣ m → m = n
id                                                 
src                                                     
typ                                                
1238  | m        0        h₁ h₂ := eq_zero_of_zero_dvd h₂
id                          └┘    └─────────────────┘
src                               └─────────────────┘
typ                         └┘    └─────────────────┘
1239  | 0        n        h₁ h₂ := (eq_zero_of_zero_dvd h₁).symm
id                       └┘        └─────────────────┘    └──┘
src                                └─────────────────┘    └──┘
typ                      └┘        └─────────────────┘    └──┘
1240  | (succ m) (succ n) h₁ h₂ := le_antisymm (le_of_dvd (succ_pos _) h₁) (le_of_dvd (succ_pos _) h₂)
id               └──┘    └┘ └┘    └─────────┘  └───────┘  └──────┘         └───────┘  └──────┘
src              └──┘             └─────────┘  └───────┘  └──────┘         └───────┘  └──────┘
typ              └──┘    └┘ └┘    └─────────┘  └───────┘  └──────┘         └───────┘  └──────┘
1241  
1242  theorem pos_of_dvd_of_pos {m n : ℕ} (H1 : m ∣ n) (H2 : n > 0) : m > 0 :=
id                                                              
src                                                                 
typ                                                             
1243  nat.pos_of_ne_zero $ λm0, by rw m0 at H1; rw eq_zero_of_zero_dvd H1 at H2; exact lt_irrefl _ H2
id   └────────────────┘    └┘        └┘           └─────────────────┘ └┘              └───────┘   └┘
src  └────────────────┘           └─┘  └────┘  └─┘└─────────────────┘  └────┘  └────┘└───────┘└─┘  
typ  └────────────────┘    └┘     └─┘└┘└────┘  └─┘└─────────────────┘└┘└────┘  └────┘└───────┘└─┘└┘
doc                               └─┘  └────┘  └─┘                     └────┘  └────┘         └─┘  
txt                               └─┘  └────┘  └─┘                     └────┘  └────┘         └─┘  
par                               └─┘  └────┘  └─┘                     └────┘  └────┘         └─┘  
pid                                   └────┘                         └────┘                └─┘  
st                               └───────────────┘└─────────────────┘└───────────────────────────────
1244  
src  
typ  
doc  
txt  
par  
pid  
st   
1245  theorem eq_one_of_dvd_one {n : ℕ} (H : n ∣ 1) : n = 1 :=
id                                                 
src                                                  
typ                                                
1246  le_antisymm (le_of_dvd dec_trivial H) (pos_of_dvd_of_pos H dec_trivial)
id   └─────────┘  └───────┘ └─────────┘    └───────────────┘  └─────────┘
src  └─────────┘  └───────┘ └─────────┘     └───────────────┘   └─────────┘
typ  └─────────┘  └───────┘ └─────────┘    └───────────────┘  └─────────┘
doc                         └─────────┘                         └─────────┘
1247  
1248  theorem dvd_of_mod_eq_zero {m n : ℕ} (H : n % m = 0) : m ∣ n :=
id                                                       
src                                                        
typ                                                      
1249  dvd.intro (n / m) $ let t := mod_add_div n m in by simp [H] at t; exact t
id   └───────┘                └─────────┘                             
src  └───────┘                   └─────────┘           └────┘ └────┘  └────┘ 
typ  └───────┘                └─────────┘         └────┘└────┘  └────┘
doc                                                     └────┘ └────┘  └────┘ 
txt                                                     └────┘ └────┘  └────┘ 
par                                                     └────┘ └────┘  └────┘ 
pid                                                          └──┘        
st                                                     └───────────────────────
1250  
src  
typ  
doc  
txt  
par  
pid  
st   
1251  theorem mod_eq_zero_of_dvd {m n : ℕ} (H : m ∣ n) : n % m = 0 :=
id                                                     
src                                                        
typ                                                    
1252  dvd.elim H (λ z H1, by rw [H1, mul_mod_right])
id   └──────┘      └┘         └┘  └───────────┘
src  └──────┘               └──┘  └┘└───────────┘
typ  └──────┘      └┘     └──┘└┘└┘└───────────┘
doc                         └──┘  └┘             
txt                         └──┘  └┘             
par                         └──┘  └┘             
pid                           └┘  └┘             
st                         └─────┘└─────────────┘
1253  
1254  theorem dvd_iff_mod_eq_zero (m n : ℕ) : m ∣ n ↔ n % m = 0 :=
id                                                 
src                                                    
typ                                                
1255  ⟨mod_eq_zero_of_dvd, dvd_of_mod_eq_zero⟩
id    └────────────────┘  └────────────────┘
src   └────────────────┘  └────────────────┘
typ   └────────────────┘  └────────────────┘
1256  
1257  instance decidable_dvd : @decidable_rel ℕ (∣) :=
id                             └───────────┘  
src                            └───────────┘  
typ                            └───────────┘  
1258  λm n, decidable_of_decidable_of_iff (by apply_instance) (dvd_iff_mod_eq_zero _ _).symm
id       └───────────────────────────┘                      └─────────────────┘     └──┘
src        └───────────────────────────┘     └────────────┘   └─────────────────┘     └──┘
typ      └───────────────────────────┘     └────────────┘   └─────────────────┘     └──┘
doc                                          └────────────┘
txt                                          └────────────┘
par                                          └────────────┘
st                                          └─────────────┘
1259  
1260  protected theorem mul_div_cancel' {m n : ℕ} (H : n ∣ m) : n * (m / n) = m :=
id                                                                 
src                                                                    
typ                                                                
1261  let t := mod_add_div m n in by rwa [mod_eq_zero_of_dvd H, zero_add] at t
id           └─────────┘              └────────────────┘   └──────┘
src           └─────────┘           └───┘└────────────────┘ └┘└──────┘└──────
typ          └─────────┘         └───┘└────────────────┘└┘└──────┘└──────
doc                                 └───┘                   └┘        └──────
txt                                 └───┘                   └┘        └──────
par                                 └───┘                   └┘        └──────
pid                                    └┘                   └┘        └───┘
st                                 └────────────────────────┘└────────┘└─────
1262  
src  
typ  
doc  
txt  
par  
pid  
st   
1263  protected theorem div_mul_cancel {m n : ℕ} (H : n ∣ m) : m / n * n = m :=
id                                                              
src                                                                 
typ                                                             
1264  by rw [mul_comm, nat.mul_div_cancel' H]
id          └──────┘  └─────────────────┘ 
src     └──┘└──────┘└┘└─────────────────┘ └─
typ     └──┘└──────┘└┘└─────────────────┘└─
doc     └──┘        └┘                    └─
txt     └──┘        └┘                    └─
par     └──┘        └┘                    └─
pid       └┘        └┘                    
st     └───────────┘└─────────────────────┘
1265  
src  
typ  
doc  
txt  
par  
pid  
st   
1266  protected theorem mul_div_assoc (m : ℕ) {n k : ℕ} (H : k ∣ n) : m * n / k = m * (n / k) :=
id                                                                         
src                                                                              
typ                                                                        
1267  or.elim (eq_zero_or_pos k)
id   └─────┘  └────────────┘ 
src  └─────┘  └────────────┘
typ  └─────┘  └────────────┘ 
1268    (λh, by rw [h, nat.div_zero, nat.div_zero, mul_zero])
id                  └──────────┘  └──────────┘  └──────┘
src            └──┘ └┘└──────────┘└┘└──────────┘└┘└──────┘
typ           └──┘└┘└──────────┘└┘└──────────┘└┘└──────┘
doc            └──┘ └┘            └┘            └┘        
txt            └──┘ └┘            └┘            └┘        
par            └──┘ └┘            └┘            └┘        
pid              └┘ └┘            └┘            └┘        
st            └────┘└────────────┘└────────────┘└────────┘
1269    (λh, have m * n / k = m * (n / k * k) / k, by rw nat.div_mul_cancel H,
id                                      └────────────────┘ 
src                                           └─┘└────────────────┘
typ                                  └─┘└────────────────┘
doc                                                  └─┘                  
txt                                                  └─┘                  
par                                                  └─┘                  
pid                                                                      
st                                                  └──────────────────────┘
1270         by rw[this, ← mul_assoc, nat.mul_div_cancel _ h])
id                └──┘    └───────┘  └────────────────┘   
src            └─┘    └──┘└───────┘└┘└────────────────┘└─┘ 
typ            └─┘└──┘└──┘└───────┘└┘└────────────────┘└─┘
doc            └─┘    └──┘         └┘                  └─┘ 
txt            └─┘    └──┘         └┘                  └─┘ 
par            └─┘    └──┘         └┘                  └─┘ 
pid                  └──┘         └┘                  └─┘ 
st            └──────┘└───────────┘└──────────────────────┘
1271  
1272  theorem dvd_of_mul_dvd_mul_left {m n k : ℕ} (kpos : k > 0) (H : k * m ∣ k * n) : m ∣ n :=
id                                                                            
src                                                                                
typ                                                                           
1273  dvd.elim H (λl H1, by rw mul_assoc at H1; exact ⟨_, eq_of_mul_eq_mul_left kpos H1⟩)
id   └──────┘     └┘        └───────┘                  └───────────────────┘ └──┘ └┘
src  └──────┘              └─┘└───────┘└────┘  └────┘ └─┘└───────────────────┘      
typ  └──────┘     └┘     └─┘└───────┘└────┘  └────┘ └─┘└───────────────────┘└──┘└┘
doc                        └─┘         └────┘  └────┘ └─┘                           
txt                        └─┘         └────┘  └────┘ └─┘                           
par                        └─┘         └────┘  └────┘ └─┘                           
pid                                   └────┘        └─┘                           
st                        └───────────────────────────────────────────────────────────┘
1274  
1275  theorem dvd_of_mul_dvd_mul_right {m n k : ℕ} (kpos : k > 0) (H : m * k ∣ n * k) : m ∣ n :=
id                                                                             
src                                                                                 
typ                                                                            
1276  by rw [mul_comm m k, mul_comm n k] at H; exact dvd_of_mul_dvd_mul_left kpos H
id          └──────┘    └──────┘                └─────────────────────┘ └──┘ 
src     └──┘└──────┘  └┘└──────┘  └────┘  └────┘└─────────────────────┘     
typ     └──┘└──────┘└┘└──────┘└────┘  └────┘└─────────────────────┘└──┘
doc     └──┘          └┘          └────┘  └────┘                            
txt     └──┘          └┘          └────┘  └────┘                            
par     └──┘          └┘          └────┘  └────┘                            
pid       └┘          └┘          └───┘                                   
st     └───────────────┘└────────────┘└───────────────────────────────────────────
1277  
src  
typ  
doc  
txt  
par  
pid  
st   
1278  /- pow -/
src  ──────────
typ  ──────────
doc  ──────────
txt  ──────────
par  ──────────
pid  ──────────
st   ──────────
1279  
src  
typ  
doc  
txt  
par  
pid  
st   
1280  @[simp] theorem pow_one (b : ℕ) : b^1 = b := by simp [pow_succ]
id                                                    └──────┘
src                                               └────┘└──────┘└─
typ                                             └────┘└──────┘└─
doc    └──┘                                          └────┘        └─
txt                                                  └────┘        └─
par                                                  └────┘        └─
pid                                                              
st                                                  └────────────────
1281  
src  
typ  
doc  
txt  
par  
pid  
st   
1282  theorem pow_le_pow_of_le_left {x y : ℕ} (H : x ≤ y) : ∀ i : ℕ, x^i ≤ y^i
id                                                              
src                                                                   
typ                                                             
1283  | 0 := le_refl _
id          └─────┘
src         └─────┘
typ         └─────┘
1284  | (succ i) := mul_le_mul (pow_le_pow_of_le_left i) H (zero_le _) (zero_le _)
id      └──┘      └────────┘  └───────────────────┘      └─────┘     └─────┘
src     └──┘       └────────┘                              └─────┘     └─────┘
typ     └──┘      └────────┘  └───────────────────┘      └─────┘     └─────┘
1285  
1286  theorem pow_le_pow_of_le_right {x : ℕ} (H : x > 0) {i : ℕ} : ∀ {j}, i ≤ j → x^i ≤ x^j
id                                                                        
src                                                                               
typ                                                                       
1287  | 0        h := by rw eq_zero_of_le_zero h; apply le_refl
id                         └────────────────┘ 
src                     └─┘└────────────────┘   └────┘       
typ                     └─┘└────────────────┘  └────┘       
doc                     └─┘                     └────┘       
txt                     └─┘                     └────┘       
par                     └─┘                     └────┘       
pid                                                        
st                     └──────────────────────────────────────┘
1288  | (succ j) h := (lt_or_eq_of_le h).elim
id      └──┘         └────────────┘   └──┘
src     └──┘          └────────────┘   └──┘
typ     └──┘         └────────────┘   └──┘
1289    (λhl, by rw [pow_succ, ← mul_one (x^i)]; exact
id       └┘         └──────┘    └─────┘  
src             └──┘└──────┘└──┘└─────┘   └┘  └─────
typ      └┘     └──┘└──────┘└──┘└─────┘ └┘  └─────
doc             └──┘        └──┘           └┘  └─────
txt             └──┘        └──┘           └┘  └─────
par             └──┘        └──┘           └┘  └─────
pid               └┘        └──┘           └┘       
st             └───────────┘└───────────────┘└───────
1290      mul_le_mul (pow_le_pow_of_le_right $ le_of_lt_succ hl) H (zero_le _) (zero_le _))
id       └────────┘  └────────────────────┘   └───────────┘ └┘                └─────┘
src  ───┘└────────┘                        └───────────┘  └┘         └──┘ └─────┘└─┘
typ  ───┘└────────┘ └────────────────────┘ └───────────┘└┘└┘        └──┘ └─────┘└─┘
doc  ───┘                                                 └┘         └──┘        └─┘
txt  ───┘                                                 └┘         └──┘        └─┘
par  ───┘                                                 └┘         └──┘        └─┘
pid  ───┘                                                 └┘         └──┘        └─┘
st   ───────────────────────────────────────────────────────────────────────────────────┘
1291    (λe, by rw e; refl)
id               
src            └─┘   └──┘
typ           └─┘  └──┘
doc            └─┘   └──┘
txt            └─┘   └──┘
par            └─┘   └──┘
pid              
st            └─────────┘
1292  
1293  theorem pos_pow_of_pos {b : ℕ} (n : ℕ) (h : 0 < b) : 0 < b^n :=
id                                                       
src                                                        
typ                                                      
1294  pow_le_pow_of_le_right h (zero_le _)
id   └────────────────────┘   └─────┘
src  └────────────────────┘    └─────┘
typ  └────────────────────┘   └─────┘
1295  
1296  theorem zero_pow {n : ℕ} (h : 0 < n) : 0^n = 0 :=
id                                         
src                                          
typ                                        
1297  by rw [← succ_pred_eq_of_pos h, pow_succ, mul_zero]
id            └─────────────────┘   └──────┘  └──────┘
src     └────┘└─────────────────┘ └┘└──────┘└┘└──────┘└─
typ     └────┘└─────────────────┘└┘└──────┘└┘└──────┘└─
doc     └────┘                    └┘        └┘        └─
txt     └────┘                    └┘        └┘        └─
par     └────┘                    └┘        └┘        └─
pid       └──┘                    └┘        └┘        
st     └──────────────────────────┘└────────┘└────────┘
1298  
src  
typ  
doc  
txt  
par  
pid  
st   
1299  theorem pow_lt_pow_of_lt_left {x y : ℕ} (H : x < y) {i} (h : i > 0) : x^i < y^i :=
id                                                                     
src                                                                          
typ                                                                    
1300  begin
st   └─────
1301    cases i with i, { exact absurd h (not_lt_zero _) },
id                            └────┘   └─────────┘
src    └────┘ └─────┘    └────┘└────┘  └─────────┘└──┘
typ    └────┘└─────┘    └────┘└────┘ └─────────┘└──┘
doc    └────┘ └─────┘    └────┘                   └──┘
txt    └────┘ └─────┘    └────┘                   └──┘
par    └────┘ └─────┘    └────┘                   └──┘
pid          └─────┘                            └─┘
st   ───────────────┘└──┘└─────────────────────────────┘└┘
1302    rw [pow_succ, pow_succ],
id         └──────┘  └──────┘
src    └──┘└──────┘└┘└──────┘
typ    └──┘└──────┘└┘└──────┘
doc    └──┘        └┘        
txt    └──┘        └┘        
par    └──┘        └┘        
pid      └┘        └┘        
st   ─────────────┘└────────┘└─
1303    exact mul_lt_mul' (pow_le_pow_of_le_left (le_of_lt H) _) H (zero_le _)
id           └─────────┘  └───────────────────┘  └──────┘
src    └────┘└─────────┘ └───────────────────┘ └──────┘ └───┘         └───
typ    └────┘└─────────┘ └───────────────────┘ └──────┘ └───┘         └───
doc    └────┘                                           └───┘         └───
txt    └────┘                                           └───┘         └───
par    └────┘                                           └───┘         └───
pid                                                    └───┘         └───
st   ─────────────────────────────────────────────────────────────────────────
1304      (pos_pow_of_pos _ $ lt_of_le_of_lt (zero_le _) H)
id        └────────────┘     └────────────┘  └─────┘    
src  ───┘ └────────────┘└─┘ └────────────┘ └─────┘└──┘ └┘
typ  ───┘ └────────────┘└─┘ └────────────┘ └─────┘└──┘└┘
doc  ───┘               └─┘                       └──┘ └┘
txt  ───┘               └─┘                       └──┘ └┘
par  ───┘               └─┘                       └──┘ └┘
pid  ───┘               └─┘                       └──┘ 
st   ─────────────────────────────────────────────────────┘
1305  end
st   └─┘
1306  
1307  theorem pow_lt_pow_of_lt_right {x : ℕ} (H : x > 1) {i j : ℕ} (h : i < j) : x^i < x^j :=
id                                                                         
src                                                                              
typ                                                                        
1308  begin
st   └─────
1309    have xpos := lt_of_succ_lt H,
id                  └───────────┘ 
src    └───────────┘└───────────┘
typ    └───────────┘└───────────┘
doc    └───────────┘             
txt    └───────────┘             
par    └───────────┘             
pid    └───────┘└─┘             
st   ─────────────────────────────┘└─
1310    refine lt_of_lt_of_le _ (pow_le_pow_of_le_right xpos h),
id            └────────────┘    └────────────────────┘ └──┘ 
src    └─────┘└────────────┘└─┘ └────────────────────┘     
typ    └─────┘└────────────┘└─┘ └────────────────────┘└──┘
doc    └─────┘              └─┘                            
txt    └─────┘              └─┘                            
par    └─────┘              └─┘                            
pid                        └─┘                            
st   ────────────────────────────────────────────────────────┘└─
1311    rw [← mul_one (x^i), pow_succ],
id           └─────┘     └──────┘
src    └────┘└─────┘   └─┘└──────┘
typ    └────┘└─────┘ └─┘└──────┘
doc    └────┘           └─┘        
txt    └────┘           └─┘        
par    └────┘           └─┘        
pid      └──┘           └─┘        
st   ────────────────────┘└────────┘└──
1312    exact nat.mul_lt_mul_of_pos_left H (pos_pow_of_pos _ xpos)
id           └────────────────────────┘   └────────────┘   └──┘
src    └────┘└────────────────────────┘  └────────────┘└─┘    └┘
typ    └────┘└────────────────────────┘ └────────────┘└─┘└──┘└┘
doc    └────┘                                          └─┘    └┘
txt    └────┘                                          └─┘    └┘
par    └────┘                                          └─┘    └┘
pid                                                   └─┘    
st   ────────────────────────────────────────────────────────────┘
1313  end
st   └─┘
1314  
1315  /- mod / div / pow -/
1316  
1317  local attribute [simp] mul_comm
id                          └──────┘
src                         └──────┘
typ                         └──────┘
doc                   └──┘
1318  
1319  theorem mod_pow_succ {b : ℕ} (b_pos : b > 0) (w m : ℕ)
id                                                    
src                                                    
typ                                                   
1320  : m % (b^succ w) = b * (m/b % b^w) + m % b :=
id        └──┘              
src         └──┘                    
typ       └──┘              
1321  begin
st   └─────
1322    apply nat.strong_induction_on m,
id           └─────────────────────┘ 
src    └────┘└─────────────────────┘
typ    └────┘└─────────────────────┘
doc    └────┘                       
txt    └────┘                       
par    └────┘                       
pid                                
st   ────────────────────────────────┘└─
1323    clear m,
src    └─────┘
typ    └─────┘
doc    └─────┘
txt    └─────┘
par    └─────┘
pid         └┘
st   ────────┘└─
1324    intros p IH,
src    └─────────┘
typ    └─────────┘
doc    └─────────┘
txt    └─────────┘
par    └─────────┘
pid          └───┘
st   ────────────┘└─
1325    cases lt_or_ge p (b^succ w) with h₁ h₁,
id           └──────┘   └──┘ 
src    └────┘└──────┘   └──┘ └──────────┘
typ    └────┘└──────┘ └──┘└──────────┘
doc    └────┘                 └──────────┘
txt    └────┘                 └──────────┘
par    └────┘                 └──────────┘
pid                          └─────────┘
st   ───────────────────────────────────────┘└─
1326    -- base case: p < b^succ w
st   ─────────────────────────────
1327    { have h₂ : p / b < b^w,
id                       
src      └────────┘  
typ      └────────┘  
doc      └────────┘    
txt      └────────┘    
par      └────────┘    
pid      └─────┘└─┘    
st   ───┘└───────────────────┘└─
1328      { rw [div_lt_iff_lt_mul p _ b_pos],
id             └───────────────┘    └───┘
src        └──┘└───────────────┘ └─┘     
typ        └──┘└───────────────┘└─┘└───┘
doc        └──┘                  └─┘     
txt        └──┘                  └─┘     
par        └──┘                  └─┘     
pid          └┘                  └─┘     
st   ─────┘└─────────────────────────────┘└──
1329        simp [pow_succ] at h₁,
id               └──────┘
src        └────┘└──────┘└─────┘
typ        └────┘└──────┘└─────┘
doc        └────┘        └─────┘
txt        └────┘        └─────┘
par        └────┘        └─────┘
pid                    └───┘
st   ──────────────────────────┘└─
1330        simp [h₁] },
id               └┘
src        └────┘  └┘
typ        └────┘└┘└┘
doc        └────┘  └┘
txt        └────┘  └┘
par        └────┘  └┘
pid              
st   ───────────────┘└┘
1331      rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂],
id           └──────────┘ └┘  └──────────┘ └┘
src      └──┘└──────────┘  └┘└──────────┘  
typ      └──┘└──────────┘└┘└┘└──────────┘└┘
doc      └──┘              └┘              
txt      └──┘              └┘              
par      └──┘              └┘              
pid        └┘              └┘              
st   ──────────────────────┘└───────────────┘└──
1332      simp [mod_add_div] },
id             └─────────┘
src      └────┘└─────────┘└┘
typ      └────┘└─────────┘└┘
doc      └────┘           └┘
txt      └────┘           └┘
par      └────┘           └┘
pid                     
st   ──────────────────────┘└┘
1333    -- step: p ≥ b^succ w
st   ────────────────────────
1334    { -- Generate condiition for induction principal
st   ───────────────────────────────────────────────────
1335      have h₂ : p - b^succ w < p,
id                     └──┘    
src      └────────┘   └──┘  
typ      └────────┘  └──┘ 
doc      └────────┘          
txt      └────────┘          
par      └────────┘          
pid      └─────┘└─┘          
st   ─────────────────────────────┘└─
1336      { apply sub_lt_of_pos_le _ _ (pos_pow_of_pos _ b_pos) h₁ },
id               └──────────────┘      └────────────┘   └───┘  └┘
src        └────┘└──────────────┘└───┘ └────────────┘└─┘     └┘  
typ        └────┘└──────────────┘└───┘ └────────────┘└─┘└───┘└┘└┘
doc        └────┘                └───┘               └─┘     └┘  
txt        └────┘                └───┘               └─┘     └┘  
par        └────┘                └───┘               └─┘     └┘  
pid                             └───┘               └─┘     └┘  
st   ─────┘└─────────────────────────────────────────────────────┘└┘
1337  
st   
1338      -- Apply induction
st   ───────────────────────
1339      rw [mod_eq_sub_mod h₁, IH _ h₂],
id           └────────────┘ └┘  └┘   └┘
src      └──┘└────────────┘  └┘  └─┘  
typ      └──┘└────────────┘└┘└┘└┘└─┘└┘
doc      └──┘                └┘  └─┘  
txt      └──┘                └┘  └─┘  
par      └──┘                └┘  └─┘  
pid        └┘                └┘  └─┘  
st   ────────────────────────┘└───────┘└──
1340      -- Normalize goal and h1
st   ─────────────────────────────
1341      simp [pow_succ],
id             └──────┘
src      └────┘└──────┘
typ      └────┘└──────┘
doc      └────┘        
txt      └────┘        
par      └────┘        
pid                  
st   ──────────────────┘└─
1342      simp [ge, pow_succ] at h₁,
id             └┘  └──────┘
src      └────┘└┘└┘└──────┘└─────┘
typ      └────┘└┘└┘└──────┘└─────┘
doc      └────┘  └┘        └─────┘
txt      └────┘  └┘        └─────┘
par      └────┘  └┘        └─────┘
pid            └┘        └───┘
st   ────────────────────────────┘└─
1343      -- Pull subtraction outside mod and div
st   ────────────────────────────────────────────
1344      rw [sub_mul_mod _ _ _ h₁, sub_mul_div _ _ _ h₁],
id           └─────────┘       └┘  └─────────┘       └┘
src      └──┘└─────────┘└─────┘  └┘└─────────┘└─────┘  
typ      └──┘└─────────┘└─────┘└┘└┘└─────────┘└─────┘└┘
doc      └──┘           └─────┘  └┘           └─────┘  
txt      └──┘           └─────┘  └┘           └─────┘  
par      └──┘           └─────┘  └┘           └─────┘  
pid        └┘           └─────┘  └┘           └─────┘  
st   ───────────────────────────┘└────────────────────┘└──
1345      -- Cancel subtraction inside mod b^w
st   ─────────────────────────────────────────
1346      have p_b_ge :  b^w ≤ p / b,
id                             
src      └─────────────┘     
typ      └─────────────┘   
doc      └─────────────┘      
txt      └─────────────┘      
par      └─────────────┘      
pid      └─────────┘└──┘      
st   ─────────────────────────────┘└─
1347      { rw [le_div_iff_mul_le _ _ b_pos],
id             └───────────────┘     └───┘
src        └──┘└───────────────┘└───┘     
typ        └──┘└───────────────┘└───┘└───┘
doc        └──┘                 └───┘     
txt        └──┘                 └───┘     
par        └──┘                 └───┘     
pid          └┘                 └───┘     
st   ─────┘└─────────────────────────────┘└──
1348        simp [h₁] },
id               └┘
src        └────┘  └┘
typ        └────┘└┘└┘
doc        └────┘  └┘
txt        └────┘  └┘
par        └────┘  └┘
pid              
st   ───────────────┘└┘
1349      rw [eq.symm (mod_eq_sub_mod p_b_ge)] }
id           └─────┘  └────────────┘ └────┘
src      └──┘└─────┘ └────────────┘      └─┘
typ      └──┘└─────┘ └────────────┘└────┘└─┘
doc      └──┘                            └─┘
txt      └──┘                            └─┘
par      └──┘                            └─┘
pid        └┘                            └┘
st   ──────────────────────────────────────┘└─
1350  end
st   ──┘
1351  
1352  lemma div_lt_self {n m : nat} : n > 0 → m > 1 → n / m < n :=
id                            └─┘                    
src                           └─┘                       
typ                           └─┘                    
1353  begin
st   └─────
1354    intros h₁ h₂,
src    └──────────┘
typ    └──────────┘
doc    └──────────┘
txt    └──────────┘
par    └──────────┘
pid          └────┘
st   ─────────────┘└─
1355    have m_pos : m > 0, { apply lt_trans _ h₂, comp_val },
id                               └──────┘   └┘
src    └───────────┘ └┘    └────┘└──────┘└─┘    └───────┘
typ    └───────────┘└┘    └────┘└──────┘└─┘└┘  └───────┘
doc    └───────────┘  └┘    └────┘        └─┘    └───────┘
txt    └───────────┘  └┘    └────┘        └─┘    └───────┘
par    └───────────┘  └┘    └────┘        └─┘    └───────┘
pid    └────────┘└─┘                   └─┘            
st   ───────────────────┘└──┘└─────────────────┘└─────────┘└┘
1356    suffices : 1 * n < m * n, {
id                         
src    └───────────┘   
typ    └───────────┘  
doc    └───────────┘     
txt    └───────────┘     
par    └───────────┘     
pid    └───────┘└──┘     
st   ─────────────────────────┘└──┘
1357      simp at this,
src      └──────────┘
typ      └──────────┘
doc      └──────────┘
txt      └──────────┘
par      └──────────┘
pid          └─────┘
st   └──────────────┘└─
1358      exact iff.mpr (div_lt_iff_lt_mul n n m_pos) this
id             └─────┘  └───────────────┘    └───┘  └──┘
src      └────┘└─────┘ └───────────────┘       └┘    
typ      └────┘└─────┘ └───────────────┘ └───┘└┘└──┘
doc      └────┘                                └┘    
txt      └────┘                                └┘    
par      └────┘                                └┘    
pid                                           └┘    
st   ─────────────────────────────────────────────────────
1359    },
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└┘
1360    exact mul_lt_mul h₂ (le_refl _) h₁ (nat.zero_le _)
id           └────────┘ └┘  └─────┘    └┘  └─────────┘
src    └────┘└────────┘   └─────┘└──┘   └─────────┘└──┘
typ    └────┘└────────┘└┘ └─────┘└──┘└┘ └─────────┘└──┘
doc    └────┘                    └──┘              └──┘
txt    └────┘                    └──┘              └──┘
par    └────┘                    └──┘              └──┘
pid                             └──┘              └─┘
st   ────────────────────────────────────────────────────┘
1361  end
st   └─┘
1362  
1363  end nat